您的位置:首页 > 其它

Reverse Integer - Leetcode

2015-10-19 17:22 183 查看
题目补充要求:如果输入的int很大,经过逆转之后会有越界的可能。

例如:x = 1147483648,result = 8463847411,结果明显越界了,因此在这里我们需要对是否越界进行一个判断,如果越界则return 0。int表示数的范围是[-2147483648,2147483648)。

相关知识:见博文 计算机编码与变量范围

本题思路简单,但要注意判断是正是负。

class Solution {
public:
int reverse(int x) {
long long k=0;
long long y=0;//这里之所以要定义一个long long型的,是因为在x=-2147483648时,取正会越界。
bool flag=x>0?true:false;
if(flag==false)
y=-x;
else y=x;
int i=10;
while(y!=0)
{
k=k*10+y%i;
y=y/i;
}
if(k>2147483647||(flag==false && k >2147483648)) return 0;  //判断是否越界
if(flag==false) return (int)(-k);
else return (int)k;
}
};


(我觉得代码没问题啊,为什么不能通过。。)经过昨天笔者查看资料外加问大神同学,最后明白一二,现在总结一下问题以及改进办法。

1.在mian()函数中定义x=-2147483648(也就是-2^31),报错:C4146 一元负运算符应用于无符号类型,结果仍为无符号类型 。

虽然x是在int的表示范围内。由于编译器收到的源代码都是字符串形式的,-2147483648对于编译器是字面量,编译器看不懂字面量,需要将字面量转化成具体数值,因此编译器在翻译 “int x = -2147483648;” 这句源代码的时候,编译器的处理过程是这样的:

a. 提取 - 号

b.提取数字部分先翻译成一个正整数 temp

c. 将 - 号应用到 正整数 上,构成最后的结果

unsigned int temp=2147483648; //b步(因为提取出的数值部分2^31超过int的表示范围,所以编译器用unsigned int 来存储)
temp=-temp;  //c步 (因为是用无符号数来存储数值的,所以对无符号数取负是错误的,因此会报错,报错发生在这一步)
int n = temp;  //c步


因此在mian()中定义 x=-2147483647-1或者-2147483646-2或者0x80000000就不会报错。

2.在x=-2147483648时,为什么y=-2147483648?

因为-2^31是一个比较特殊的数字,当你对它进行取负的时候(补码符号位不变,其余各位取反,最后加1),最后还是它本身。等于这个程序最后的K的符号还是和x一样,所以在判断是否越界时出现问题。将k >2147483648改成k<-2147483648,就可以AC。

第二种解决方式:

这里是先将x逐位分离,再改变正负号。长整数用16进制表示更为清晰直观。

int reverse(int x) {
int num[32];
for (int i = 0; i < 32; i++)
num[i] = 0;
bool positive = x > 0 ? true : false;
int j = 0;
while (x != 0)
{
int digit = x % 10;
num[j++] = positive ? digit : -digit;
x = x / 10;
}
long long result = 0;
int m = 0;
while (m < j)
{
result = result * 10 + num[m++];
}
if (positive == false && result>0x80000000) return 0;
else if (positive&&result > 0x7fffffff) return 0;
return positive ? result : -result;
}


补充:0x80000000=-2^31,0x80000001=-2^31+1(仍在范围之类,并不是表示越界的数。0x80000000一直+1就是将数字变大(因为是负数))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 编码