鱼C论坛

 找回密码
 立即注册
查看: 2982|回复: 12

[技术交流] 007_整数翻转

[复制链接]
发表于 2019-5-6 19:09:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 风扫地 于 2019-5-7 19:31 编辑

题目来源:力扣
算法好难,只好从简单的题刷起。
  1. /*
  2. 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
  3. 示例 1:
  4. 输入: 123
  5. 输出: 321
  6. 示例 2:
  7. 输入: -123
  8. 输出: -321
  9. 示例 3:
  10. 输入: 120
  11. 输出: 21
  12. 注意:
  13. 假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
  14. */
复制代码


实现方案:
  1. class Solution {
  2. public:
  3.     int reverse(int x)
  4.     {
  5.         int p_or_n        = 0               ;
  6.         int overflow_flag = 0               ;
  7.         int maxvalueLimit = 2147483647/10   ;
  8.         int ret_val       = 0               ;
  9.         do{
  10.             if(  (x == -2147483648  )
  11.                ||(x == 0            )
  12.             )
  13.             {
  14.                 ret_val = 0;
  15.                 break;
  16.             }
  17.             p_or_n  = x > 0 ? 1:-1; /* 1为正,-1为负数 */
  18.             x       = x*p_or_n;
  19.             ret_val = 0;
  20.             while(x!=0)
  21.             {
  22.                 if(ret_val>maxvalueLimit)
  23.                 {
  24.                     overflow_flag = 1;
  25.                     break;
  26.                 }
  27.                 ret_val = ret_val*10 + x % 10;
  28.                 x /= 10;
  29.             }
  30.             if(overflow_flag == 0)
  31.             {
  32.                 ret_val = ret_val * p_or_n;
  33.                 break;
  34.             }
  35.             else
  36.             {
  37.                 return 0;
  38.             }
  39.             break;
  40.         }while(0);
  41.         return ret_val;
  42.     }
  43. };
复制代码


测试代码:
  1. #include <iostream>
  2. using namespace std;

  3. int main(void)
  4. {
  5.    Solution solution;
  6.    cout << solution.reverse(-2147483648) << endl;
  7.    cout << solution.reverse(-2147483647) << endl;
  8.    cout << solution.reverse(-110)        << endl;
  9.    cout << solution.reverse(2147483641)  << endl;
  10.    return 0;
  11. }
复制代码



提交结果:
  1. /*
  2. 执行用时 : 12 ms, 在Reverse Integer的C++提交中击败了98.18% 的用户
  3. 内存消耗 : 8.4 MB, 在Reverse Integer的C++提交中击败了74.72% 的用户
  4. */
复制代码

Nice.


附录:
2^31-1=2147483647,-2^31=-2147483648
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-5-6 20:23:17 | 显示全部楼层
    楼主看看这个实现如何?
  1. #include <stdio.h>

  2. int ReversInt(const int n)
  3. {
  4.         int d , i , k , m                            ;
  5.         bool f                                       ;

  6.         f = false                                    ;
  7.         m = n                                        ;
  8.         if (m < 0) {
  9.                 m = - m                              ;
  10.                 f = true                             ;
  11.         }
  12.         d = 1                                        ;
  13.         for(d = 1 , i = m ; i > 0 ; i /= 10) d *= 10 ;
  14.         for(i = m , k = 0 , d /= 10 ; i > 0 ; i /= 10) {
  15.             k += (i % 10) * d                        ;
  16.             d /= 10                                  ;
  17.         }
  18.         if (f) k = - k                               ;
  19.         return k                                     ;
  20. }

  21. int main(void)
  22. {
  23.         int n                                        ;
  24.         scanf("%d" , & n)                            ;
  25.         printf("%d\n" , ReversInt(n))                ;
  26. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-6 20:29:48 | 显示全部楼层
jackz007 发表于 2019-5-6 20:23
楼主看看这个实现如何?

输入 1534236469
溢出了,楼上没处理溢出的情况.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-6 21:35:56 | 显示全部楼层
本帖最后由 jackz007 于 2019-5-6 21:39 编辑
风扫地 发表于 2019-5-6 20:29
输入 1534236469
溢出了,楼上没处理溢出的情况.


      虚心接受楼主的意见,现在再测呢:
  1. #include <stdio.h>

  2. int ReversInt(int m)
  3. {
  4.         int i , k                                                          ;
  5.         bool f                                                             ;

  6.         f = false                                                          ;
  7.         if(m < 0) {
  8.                 m = - m                                                    ;
  9.                 f = true                                                   ;
  10.         }
  11.         for(k = 0 , i = m ; i > 0 ; i /= 10) {
  12.                 if(k < 0x7fffffff / 10) {
  13.                         k = k * 10 + (i % 10)                              ;
  14.                 } else {
  15.                         k = 0                                              ;
  16.                         break                                              ;
  17.                 }
  18.         }
  19.         if (f && k) k = - k                                                ;
  20.         return k                                                           ;
  21. }

  22. int main(void)
  23. {
  24.         int n                                                              ;
  25.         scanf("%d" , & n)                                                  ;
  26.         printf("%d\n" , ReversInt(n))                                      ;
  27. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-7 09:00:52 | 显示全部楼层
本帖最后由 风扫地 于 2019-5-7 09:03 编辑
jackz007 发表于 2019-5-6 21:35
虚心接受楼主的意见,现在再测呢:


1.
-2147483648( -2^31  )这个测试用例挂了, -2^31  ~ 2^31 -1
最小不能取反,取反就溢出。
2.
测试用例 1463847412 挂了,实际上没溢出,但判断成溢出了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-7 10:28:18 | 显示全部楼层
本帖最后由 jackz007 于 2019-5-7 10:41 编辑
风扫地 发表于 2019-5-7 09:00
1.
-2147483648( -2^31  )这个测试用例挂了, -2^31  ~ 2^31 -1
最小不能取反,取反就溢出。


    现在再测
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int ReversInt(int m)
  4. {
  5.         int i , k                     ;
  6.         for(k = 0 , i = m ; abs(i) > 0 ; i /= 10) {
  7.                 k = k * 10 + (i % 10) ;
  8.                 if((m > 0 && k <= 0) || (m < 0 && k >= 0)) {
  9.                         k = 0         ;
  10.                         break         ;
  11.                 }
  12.         }
  13.         return k                      ;
  14. }

  15. int main(void)
  16. {
  17.         int n                         ;
  18.         scanf("%d" , & n)             ;
  19.         printf("%d\n" , ReversInt(n)) ;
  20. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-7 10:38:06 | 显示全部楼层



执行出错信息:  runtime error: signed integer overflow: 964632435 * 10 cannot be represented in type 'int' (solution.cpp)
最后执行的输入: 1534236469

还是溢出的问题~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-7 10:53:36 | 显示全部楼层

最后执行的输入: 1534236469
执行出错信息:runtime error: signed integer overflow: 964632435 * 10 cannot be represented in type 'int' (solution.cpp)


溢出的问题还是木有处理啊~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-7 14:42:30 | 显示全部楼层
风扫地 发表于 2019-5-7 10:53
最后执行的输入: 1534236469
执行出错信息:runtime error: signed integer overflow: 964632435 * 10  ...

    锲而不舍,彻底解决溢出问题:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int ReversInt(int m)
  4. {
  5.         int i , k                             ;
  6.         for(k = 0 , i = m ; abs(i) > 0 ; i /= 10) {
  7.                 if((m > 0 && k + (i % 10) > 214748371) || (m < 0 && k + (i % 10) < -214748372)) {
  8.                         k = 0                 ;
  9.                         break                 ;
  10.                 } else {
  11.                         k = k * 10 + (i % 10) ;
  12.                 }
  13.         }
  14.         return k                              ;
  15. }

  16. int main(void)
  17. {
  18.         int n                                 ;
  19.         scanf("%d" , & n)                     ;
  20.         printf("%d\n" , ReversInt(n))         ;
  21. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-7 17:24:10 | 显示全部楼层
jackz007 发表于 2019-5-7 14:42
锲而不舍,彻底解决溢出问题:

1563847412
-2147483648
还是溢出了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-7 18:31:14 | 显示全部楼层
风扫地 发表于 2019-5-7 17:24
1563847412
-2147483648
还是溢出了。

    楼主厉害,再把这个攻破!
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int ReversInt(int m)
  4. {
  5.         int i , k                             ;
  6.         for(k = 0 , i = m ; abs(i) > 0 ; i /= 10) {
  7.                 if((m > 0 && (k > 214748364 || (k == 214748364 && i % 10 > 7))) || (m < 0 && (k < -214748364 || (k == -214748364 && i % 10 < -8)))) {
  8.                         k = 0                 ;
  9.                         break                 ;
  10.                 } else {
  11.                         k = k * 10 + (i % 10) ;
  12.                 }
  13.         }
  14.         return k                              ;
  15. }

  16. int main(void)
  17. {
  18.         int n                                 ;
  19.         scanf("%d" , & n)                     ;
  20.         printf("%d\n" , ReversInt(n))         ;
  21. }
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
风扫地 + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-7 19:29:36 | 显示全部楼层
jackz007 发表于 2019-5-7 18:31
楼主厉害,再把这个攻破!

增加一句:
        if(-2147483648 == m)
        {
            return 0;
        }


就跑完所有的测试用例了:
1032 / 1032 个通过测试用例
        状态:通过
执行用时:12 ms
       
提交时间:0 分钟之前


执行用时 : 12 ms, 在Reverse Integer的C++提交中击败了98.19% 的用户
内存消耗 : 8.2 MB, 在Reverse Integer的C++提交中击败了78.71% 的用户
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 15:12

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表