先看代码:
int fac(int n, int k)
{
if(k > 1)
return n * fac(n,k - 1 );
if (k == 0)
return 1;
}
int main()
{
int n = 0;
int k = 0;
scanf("%d %d", &n, &k);
int ret = fac(n, k);
printf("%d", ret);
}
通过递归来解决这个问题,颇有一种大事化小的感觉。
写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
输入:1729,输出:19
int Digitsum(int num)
{
if (num /10 > 0)
{
int a = num % 10;
return Digitsum(num/10) + a;
}
else {
return num % 10;
}
}
int main()
{
int num = 0;
scanf("%d", &num);
int sum = Digitsum(num);
printf("%d", sum);
}
以下是对题目三“递归实现计算一个数的每位之和”代码的详细分析及优化建议:
int Digitsum(int num) {
if (num / 10 > 0) { // 递归条件:数字多于1位
int a = num % 10; // 取最后一位数字
return Digitsum(num/10) + a; // 递归剩余部分并累加
}
else { // 基线条件:只剩1位数字
return num % 10; // 直接返回该数字
}
}
递归分解原理:
num % 10
获取当前数字的最后一位(如1729 → 9)num/10
移除最后一位(1729 → 172)执行流程示例(输入1729
):
时间复杂度:O(d)
(d为数字位数,每个数字仅处理1次)
num=0
时:
0/10=0
→ 进入else
分支0%10=0
→ 返回0(正确)num<0
的情况(题目要求非负整数)else
分支的num%10
可简化为num
(因num<10
时二者等价)a
非必需num/10>0
可改为num>=10
更直观#include
int Digitsum(int num) {
if (num < 0) return -1; // 处理非法输入
if (num < 10) return num; // 基线条件:单数字直接返回
return num % 10 + Digitsum(num / 10); // 递归累加
}
int main() {
int num;
scanf("%d", &num);
printf("Sum: %d", Digitsum(num));
return 0;
}
原代码问题 | 优化方案 | 效果 |
---|---|---|
未处理负数 | 添加if(num<0) 校验 |
避免非法输入导致逻辑错误 |
冗余变量a |
直接返回表达式 | 代码更简洁 |
终止条件冗余 | num%10 → num |
单数字时直接返回更高效 |
条件可读性 | num/10>0 → num>=10 |
逻辑更直观 |
方案 | 代码示例 | 优点 | 缺点 |
---|---|---|---|
递归 | return num%10 + Digitsum(num/10); |
逻辑简洁,直接映射数学定义 | 栈溢出风险(超大数据) |
迭代 |
代码如下:
int factorial(int n)
{
if (n >= 1)
return n * factorial(n - 1);
if (n == 0)
return 1;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = factorial(n);
printf("%d", ret);
}
int main()
{
int ret = 1;
int n = 0;
scanf("%d", &n);
while (n)
{
ret *= n;
n--;
}
printf("%d", ret);
}
代码如下:
void print_num(int num)
{
if (num / 10 > 0)
{
print_num(num / 10);
printf("%d ", num % 10);
}
else {
printf("%d ", num);
}
}
int main()
{
int num = 0;
scanf("%d", &num);
print_num(num);
}