假设我们有一个用 C 编写的程序,可以检查数字是否是回文,根本不使用任何数组(所以不要回复任何使用数组的答案)
#include <stdio.h>
#include <math.h>
int NumOfDigits(long long x) {
int sum = 1;
while (x / 10 != 0) {
sum ++;
x = x / 10;
}
return sum;
}
int isPal(long long x) {
int f, c, front, back, sum;
sum = NumOfDigits(x);
c = round(pow(10,(sum-2)));
front = x / round(pow(10,(sum - 1)));
back = x % 10;
f = 1;
while (x != 0 && f == 1 && c != 0) {
if (front == back) {
x = (x / 10) % c;
c /= 100;
sum -=2;
front = x / round(pow(10,(sum-1)));
back = x % 10;
} else {
f = 0;
}
}
if (f) {
return 1;
} else {
return 0;
}
}
int main() {
int f;
long long x;
scanf("%lld", &x);
f = isPal(x);
if (f) {
printf("yes");
} else {
printf("no");
}
printf("\n");
}
所以基本上这个算法每次都会检查第一个和最后一个数字,然后将 NumOfDigits 减少 2,所以如果我们有 345543,首先是 345543,然后是 4554、55 等等。这个程序的要点是,例如给定数字900075181570009 它说它不是回文,但这是因为计算机删除了数字左侧的 0。所以当它到达 0007518157000 时,它基本上是 7518157000,这不是一个回文数。那么,我们如何修改算法,再次不使用数组,以达到预期的结果?
在此代码中,c 值被错误地声明为
int
。
当我们执行时
#include <stdio.h>
#include <math.h>
int main()
{
int c ;
c = round(pow(10,13));
printf("%ld",c);
return 0;
}
当我们运行上面的程序时,我们收到溢出警告
main.c: In function ‘main’:
main.c:14:9: warning: overflow in conversion from ‘double’ to ‘int’ changes value from ‘1.0e+13’ to ‘2147483647’ [-Woverflow]
14 | c = round(pow(10,13));
| ^~~~~
2147483647
所以只需将
int c
更改为 unsigned long int
即可解决问题,并且效果非常好
首先,该解决方案在处理整数值时不需要
<math.h>
。
NumOfDigits
因误启动而关闭。这意味着正在比较的值将被视为数组(具有单独的元素)。
下面是一个解决方案。
isPal()
打印正在检查的两个值的base10表示形式,以验证该函数正在使用整数,而不是数组。
数组用于
main()
(isPal()
外部)中的测试对集合,仅用于演示如何在测试用例中表达带有前导/尾随零的值。 (注意:用 atoi()
转换的数字字符串规避了 C 编译器对 _ 前导零的解释,预示着源代码中的八进制或十六进制值。)
#include <stdio.h>
char *isPal( uint32_t a, uint32_t b) {
uint32_t rev = 0;
printf( "isPal( %u, %u ) - ", a, b );
for( ; b; b /= 10 )
rev = rev * 10 + b % 10;
for( ; rev <= a; rev *= 10 )
if( rev == a )
return "yes";
return "no";
}
int main( void ) {
char *vals[][2] = {
{ "123", "321" },
{ "121", "321" },
{ "0070", "7000" },
{ "50060", "06005" },
{ 0 } // terminate
};
for( size_t i = 0; vals[i][0]; i++ )
printf( "%s & %s - %s\n", vals[i][0], vals[i][1],
isPal( atoi( vals[i][0]), atoi( vals[i][1] ) ) );
return 0;
}
结果:
isPal( 123, 321 ) - 123 & 321 - yes
isPal( 121, 321 ) - 121 & 321 - no
isPal( 70, 7000 ) - 0070 & 7000 - yes
isPal( 50060, 6005 ) - 50060 & 06005 - yes
当别人说某件事不可能时,相信他们是不健康的......