int main()
{
int i,n;
printf("Enter the number");
scanf("%d",&n);
i=pali(n);
if(n==i)
printf("Number is pall");
else
printf("Not Pall");
}
int pali(int n)
{
int r;
static sum=0;
if(n!=0)
{
r=n%10;
sum=sum*10+r;
pali(n/10);
}
return sum;
}
我使用静态变量来加总和。有没有办法不使用静态变量?
答案 0 :(得分:2)
是的,典型的("功能")方法是以函数参数的形式传递状态。这通常使得有必要/很好的第二个函数执行实际的递归,你可以通过调用状态的正确初始值来开始:
int do_pali(int sum, int n)
{
if(n != 0)
{
const int r = n % 10;
return do_pali(10 * sum + r, n / 10);
}
return sum;
}
然后公共职能变成:
int pali(int n)
{
return do_pali(0, n);
}
在具有内部功能的语言中,可以更清晰地表达(GCC支持将其作为扩展名)。
答案 1 :(得分:1)
当然,你可以这样做:
#include <stdio.h>
int pali(int n)
{
int sum = 0;
int keeper = 0;
for (int i = n; i > 0; i /= 10) {
if (keeper != 0) {
sum *= 10;
sum += (keeper - i * 10);
}
keeper = i;
}
sum *= 10;
sum += keeper;
return sum;
}
int main(int argc, char** argv)
{
int i, n;
printf("Enter the number : ");
scanf("%d",&n);
i = pali(n);
if(n == i)
printf("Number is palindrome");
else
printf("Not Palindrome");
}
使用递归更容易:
#include <stdio.h>
int pali(int n, int sum)
{
sum += n - ((n / 10) * 10);
n /= 10;
if (n > 0)
pali(n, sum * 10);
else
return sum;
}
int main(int argc, char** argv)
{
int i, n;
printf("Enter the number : ");
scanf("%d",&n);
i = pali(n, 0);
if(n == i)
printf("Number is palindrome");
else
printf("Not Palindrome");
}
只有一个参数的递归版本:
#include <stdio.h>
int pali(int n)
{
int fUnit, lUnit;
fUnit = n;
int mul = 1;
while (fUnit > 10) {
fUnit /= 10;
mul *= 10;
}
lUnit = n - ((n / 10) * 10);
n -= (fUnit * mul);
n /= 10;
if (mul == 1) return 1;
else if (fUnit == lUnit) return pali(n);
else return 0;
}
int main(int argc, char** argv)
{
int n;
printf("Enter the number : ");
scanf("%d",&n);
if(pali(n) == 1)
printf("Number is palindrome");
else
printf("Not Palindrome");
}
答案 2 :(得分:0)
由于您的函数返回sum
,您可以替换此行:
pali(n/10);
与
sum=pali(n/10);
你也必须将它移动一条线。
答案 3 :(得分:0)
以下是
的优化版本static
。#include <stdio.h>
static void perform_useless_recursion (int n)
{
if(n--)
{
perform_useless_recursion(n);
}
}
_Bool is_pali (int n)
{
perform_useless_recursion(1);
int sum = 0;
for(int i=n; i!=0; i/=10)
{
sum = sum*10 + i%10;
}
return n == sum;
}
int main (void)
{
int n=5005;
if(is_pali(n))
printf("Number is pall");
else
printf("Not Pall");
return 0;
}
通过删除perform_useless_recursion()
函数,可以进一步改进代码。
此代码的优点是实际计算由快速循环执行,而不是缓慢,危险的递归。在人工学校作业之外的现实世界中,当您编写高效且安全的代码时,没有理由编写低效且危险的代码。作为奖励,删除递归也会提供更易读的代码。
如果您对此代码进行基准测试,您会注意到它会比所有其他版本的内容更快并且消耗更少的内存。
答案 4 :(得分:0)
你可以创建一个只检查数字的第一个和最后一个数字的函数,然后传递剩下的数字。
为了更好地解释,请考虑以下情况:
pali( 1 22 0 )会检查第一个( 1 )和最后一个( 0 强>)数字。由于1!= 0 pali将返回false。
pali(1 789 1)将检查第一(1)和最后(1)。由于它们相等,所以函数会递归返回pali( 789 )(自7!= 9后它本身会返回false)。
pali( 878 )将检查8 = 8并递归返回pali( 7 )
pali( 3 )会检查第一个( 3 )和最后一个( 3 )数字是否相等并返回0。
这里的挑战是开发一种算法:
检查第一个和最后一个数字是否相同(即使它只有一个数字!)
从第一个和最后一个数字中删除数字,并在余数上调用
然后您需要做的就是应用递归。这是一个示例实现:
int pali(int number)
{
int smallDigit, bigDigit;
/* When recursion ends suceffuly*/
if (number == 0)
return 1;
/* Check for first and last digit of a number */
smallDigit = number % 10;
bigDigit = number;
while(bigDigit/10!=0)
{
bigDigit = bigDigit/10;
smallDigit = smallDigit*10;
}
/* Check to see if both digits are equal (Note: you can't use smallDigit here because it's been multiplied by 10 a few times) */
if (bigDigit != number%10)
return 0;
else
{
number = (number - smallDigit)/10; /* This is why smallDigit was multiplied by 10 a few times */
return pali(number); /* Recursion time */
}
}