Reverse digits of an integer.
Example1: x = 123, return 321 Example2: x = -123, return -321
Note: The input is assumed to be a 32-bit signed integer. Your function should return 0 when the reversed integer overflows.
问题分析:
问题很清楚,就是将十进制数的顺序反转,符号保持不变,这道题主要考察的是溢出问题,输入一个int变量,反转可能发生溢出。
知识点:
1. 数据类型 —-> 存储大小 —-> 值的大小 —-> 溢出 —->边界条件
2. 取模运算
3. printf 打印有符号、无符号、长整型数 —-> %d、%u、%ld、
4. pow函数求10^i,即10的 i 次方
5. 数组的初始化 —-> {0}可将整个字符串初始化为0
6. 常量 —-> const 或者 #define
7. 字符串 —-> C语言中没有字符串类型,用字符数组处理字符串
8. 将int转换为char,将char转换为int
自己首先想到的解法思路:
1. 求余,并将每次求余的结果写入数组中,数组最大为10;
2. 从数组中倒着将数读出来乘10的幂次方在累加,变量设为long int tmp2,防止溢出;
3. 判断变量tmp2是否溢出,返回对应值。
该方法的缺点是求余运算量较大:N%10 =N - (N/10)*10. 最后的运算时间也印证了这一点,只击败了3%的解法。
代码如下
int reverse(int x) {
int max = 2147483647;
int min = -2147483648;
signed int y;
int i, j;
int array[10] = {0};
int tmp = 0;
long int tmp2 = 0;
for (i = 0; i < 10; i++) {
tmp = x/pow(10, i);
printf("tmp = %d\n", tmp);
if (tmp == 0)
break;
array[i] = tmp%10;
printf("array[%d] = %d\n", i, array[i]);
}
for (j = 0; j < i; j++) {
tmp2 += array[j]*pow(10, i - j -1);
}
y = ((tmp2 <= max) && (tmp2 >= min)) ? tmp2: 0;
printf("%d\n%d\n%ld\n%d\n\n", y, tmp, tmp2, i);
return y;
}
参考别人的代码:
更加简洁,但效率也不高
int reverse(int x) {
const int MAX = 0x7fffffff;
const int MIN = 0x80000000;
long int tmp = 0;
int y = 0;
while (x != 0) {
tmp = tmp*10 + x%10;
x /= 10;
}
y = ((tmp >= MIN) && (tmp <= MAX))? tmp: 0;
return y;
}
高效率解法思路:
1. 将int转换为char;
2. 反转char的顺序;
3. 将char转换为int。
注意在用sscanf将char转换为long int的变量时—–> %ld,否则long int的高4个字节会出现未知数据,或者是初始化的数据,sscanf将只能影响低4个字节的存储
int reverse(int x) {
const int MAX = 0x7fffffff;
const int MIN = 0x80000000;
char string_x1[12] = {0};
char string_x2[12] = {0};
long int tmp = 0;
int i, y;
int x1_len, index;
sprintf(string_x1, "%d", x);
x1_len = strlen(string_x1);
index = (x > 0)? x1_len: x1_len - 1;
for (i = 0; i < index; i++) {
string_x2[i] = string_x1[x1_len - i - 1];
}
sscanf(string_x2, "%ld", &tmp);
tmp = (x > 0)? tmp: -tmp;
y = ((tmp >= MIN) && (tmp <= MAX))? tmp: 0;
return y;
}