实际上,我回答了另一个(有点幽默)的答案,它使用了一个绝对巨大的数组来进行表格查找,但是回想一下,如果您限制表格大小,这并不是一个坏主意。
以下函数以空间换时间。与所有优化一样,您应该在目标环境中自己分析它们。
首先是(优雅的)递归版本:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
return (val == 0) ? 0 : getSum (val / 1000) + lookup[val%1000];
}
它基本上将数字分成三位数的分组,并针对每种可能性进行固定查找。这可以轻松处理递归深度为 7 个堆栈帧的 64 位无符号值。
对于那些甚至不相信 少量递归的人(你应该这样做,因为普通程序甚至在没有递归的情况下会走得更深,甚至更深),你可以尝试迭代解决方案:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
unsigned int tot = 0;
while (val != 0) {
tot += lookup[val%1000];
val /= 1000;
}
return tot;
}
这些可能比一次一位数的解决方案快三倍,代价是一千字节的数据。如果您不反对使用 10K 或 100K,您可以将速度提高到四到五倍,但您可能需要编写一个程序来生成上面的静态数组语句 :-)
与所有优化选项一样,衡量,不要猜测!
我自己更喜欢更优雅的递归解决方案,但我也是喜欢神秘填字游戏的类型之一。随心所欲地阅读。