我写了一个递归计算数字之和的C程序,我的问题是是否有其他方法,最好是更快的方法,可以完成这个过程。
这是我的代码,也许我可以避免使用prototype函数,但我不知道这是否会使它更快。
#include <stdio.h>
int sum(int);
int main() {
int i;
scanf("%d\n", &i);
printf("%d", sum(i));
}
int sum(int x) {
int res;
if (x > 9) {
res = (sum(x % 10) + sum(x / 10));
} else {
res = x;
}
return res;
}
字符串
6条答案
按热度按时间6tr1vspr1#
正如在注解中提到的,使用递归是没有意义的。这里有一个非常简单的迭代版本,它应该更快:
字符串
请注意,这假设
x
是非负的。ioekq8ef2#
因此,明显的改进方法是摆脱上述两种方法。如果你知道目的是对数字求和,你可以把输入作为一个字符串。
字符串
根据CPU的不同,这应该比你目前拥有的快 * 很多倍。
66bbxpm53#
我的问题是,是否有任何其他方法,最好是更快的方法,可以完成这一程序。
不要使用递归。
递归并不能使代码更快,它使某些算法更容易实现,因为你不必自己做簿记。
快速排序之所以快,并不是因为它是递归的;它之所以快,是因为它通过将列表划分为部分排序的子列表,最大限度地减少了比较和交换的次数。它通常以递归的方式实现,因为它比维护自己的堆栈更容易。
相反,递归斐波纳契实现是非常慢的,因为你要多次计算相同的项(对于大的N,最多数千次)。
Lundin和Tom的解决方案是更好的方法。
现在,已经说过了所有这些,没有一个
int
会有超过10位的数字,所以各种算法之间的增量几乎是不可测量的;只有当你要在你的程序中调用这个函数 * 数千次 * 时,这才是一个问题。也许我可以避免原型函数,但我不知道这是否会使它更快。
声明的形式对代码的运行时性能没有影响。
h5qlskok4#
递归对这个函数没有帮助,在这种情况下效率很低。
下面是一个更简单的版本,可以处理正值和负值:
字符串
ig9co6j15#
虽然其他答案是正确的,但 * 一些 * C编译器 * 可能 * 实现了尾调用优化,并自动将尾递归代码转换为迭代代码。
如果我们添加一个额外的累加器参数来累加函数的运行和,我们就可以实现尾递归。
字符串
我们可以通过定义一个接受累加器的
sum_tailrec
函数,然后让sum
调用该函数,将累加器初始化为零来隐藏这个细节。mlmc2os56#
在我看来,你的递归函数应该是
字符串
因为你知道除法的余数就是数字本身,只要把它加到数字的和上,而不加最后一位数字。在某个时候,除法将是0,所以算法是有保证的。