乍一看这个题目,也太简单了吧。就算是初学C语言的小白,这种题目也是直接秒杀的。
但是!重点来了,这道题目给出了一个限制:
如何对较大的数据处理,防止在反转时溢出(即int型的变量无法储存反转后的数据),这是这道题的关键。
我们来有逻辑的思考这道题。
①符号问题:这个整数可能是负数,需要我们判断处理。
int flag; //处理正负号
if (x<0)
{
flag=0;
x=-x;
}
else
{
flag=1;
}
(p.s:其实这样做没啥必要,因为mod负数也是可以实现的,但是作者怕出问题所以先判断一下符号了)
②反转的算法:很简单,不赘述。
while(x!=0)
{
y=y*10+x%10;
x/=10;
}
③防止溢出的限定条件:【重点】
这一段需要置于循环中,并在②代码之前完成判断。
/*判断是否溢出*/
if (flag==1)
{
if ( y>( pow(2,31)-1)/10 || (y==(pow(2,31)-1)/10 && x%10>7) ) return 0;
}
else
{
if ( -y<-pow(2,31)/10 || (-y==-pow(2,31)/10 && x%10>8) ) return 0;
}
代码解释:
int型储存范围是-2147483648 ~ 2147483647。
判断没有溢出的方法就是:
(1)当前任未进位(*10)时,前面的数字已经大于214748364了,那么不管下面一个要接上去的数字x是多少,214748364x都是溢出的。
(2)当前任未进位(*10)时,前面的数字已经等于214748364了,那么是否溢出取决于下一位数字x。正数为214748364x,所以x不能大于7;负数为-217478364x,所以x不能大于8。
(p.s:C++是有INT_MAX和INT_MIN的,就不需要调用pow(x,n)函数表示int边界值了。C是否可以笔者不知,所以用了pow)
④返回值:
if(flag==0) return -y;
else return y;
⑤需要注意的一个细节:传入函数的参数须用long long型
int reverse(long long x){
/*......*/
}
当然,题目一开始给出的传入参数的类型是int,这就会导致这样的错误:
我们很清晰的看到,错误在于传入的-2147483648已经不能在用int来储存了。
所以,需要我们自己去改成long long x。
⑥完整代码:
#include<math.h>
int reverse(long long x){
int flag; //处理正负号
if (x<0)
{
flag=0;
x=-x;
}
else
{
flag=1;
}
int y=0;
while(x!=0)
{
/*判断是否溢出*/
if (flag==1)
{
if ( y>( pow(2,31)-1)/10 || (y==(pow(2,31)-1)/10 && x%10>7) ) return 0;
}
else
{
if ( -y<-pow(2,31)/10 || (-y==-pow(2,31)/10 && x%10>8) ) return 0;
}
y=y*10+x%10;
x/=10;
}
if(flag==0) return -y;
else return y;
}
执行结果: