题目描述
原题:NC57 反转数字
描述
给定一个32位的有符号整数num,将num中的数字部分反转,最后返回反转的结果
1.只反转数字部分,符号位部分不反转
3.假设本题不允许存储 64 位整数(有符号或无符号,即C++不能使用long long ,Java不能使用long等)
数据范围:
算法设计思路
反转思路:先计算整数的位数,然后通过除法、取模得到首位和末尾的数字,再交换数字。
先减一个数将原来的数字置零,然后加上新数与对应数位的乘积,就可以替换掉一个数位。
不反转符号位:新建一个变量 flag 保留符号位信息,将原数取绝对值,再反转。
超过32位有符号整数范围:若原数 num 满足:
- 数量级为 10 亿,个位大于 2
- 数量级为 10 亿,个位为 1 ~ 2,反转后数量级小于 10 亿
则可判断发生了溢出,返回 0。
算法实现(C语言)
#include<limits.h> int reverse(int x ) { if(x == INT_MIN)//INT_MIN取相反数运算,数将不变 { return 0; } bool fu = false;//x是否为负 if(x < 0) { x = -x; fu = true; } int t = x;//x绝对值的备份 bool big = false;//x的数量级是否为10亿 if(x > 1000000000) { big = true; } int f = 1;//f数量级指向首位,e数量级指向末位;将向中间迭代 int e = 1; while(x / f / 10 > 0) //得到x首位的数量级 { f *= 10; } while(f > e) { int fNum = x / f % 10;//得到首、末位数字 int eNum = x / e % 10; x = x - f * fNum + f * eNum;//交换数字 x = x - e * eNum + e * fNum; f /= 10;//向中间迭代 e *= 10; } int eNum = t % 10; if(big && (eNum > 2 || (eNum != 0 && x < 1000000000)))//反转后溢出 { return 0; } if(fu) { x = -x; } return x; }
bug记录:一个负数取相反数运算,结果不变
#include<iostream> #include<climits> using namespace std; int main(){ int x = INT_MIN; cout << x << endl; int y = -x; cout << "取相反数:" << y << endl; return 0; }
现在已经知道是因为发生了溢出,但为什么溢出了结果数的值不变?大家可以自行了解下二进制补码计数法,即与计算机底层整数的表示方法有关。
运行结果
成功通过!
结束语:
今天的分享就到这里啦,快来一起刷题叭!