c语言代码习题——递归习题

c语言代码习题——递归习题_第1张图片

题目二:递归实现n的k次方

先看代码:

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);
}
fac(2,3)
2*fac(2,2)
2 * 2*fac(2,1)
2 * 2 * 2*fac(2,0)
2 * 2 * 2 * 1=8

通过递归来解决这个问题,颇有一种大事化小的感觉。

题目三:计算一个数的每位之和(递归实现)

写一个递归函数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;      // 直接返回该数字
    }
}
✅ 核心逻辑解析
  1. 递归分解原理

    • 取末位num % 10 获取当前数字的最后一位(如1729 → 9)
    • 截断高位num/10 移除最后一位(1729 → 172)
    • 递归累加:末位值 + 剩余部分的递归结果
  2. 执行流程示例(输入1729):

    Digitsum(1729)
    9 + Digitsum(172)
    9 + (2 + Digitsum(17))
    9+2+(7 + Digitsum(1))
    9+2+7+1=19
  3. 时间复杂度:O(d)
    (d为数字位数,每个数字仅处理1次)


⚠️ 二、潜在问题与优化建议

1. 边界条件缺陷
  • 问题:当输入num=0时:
    • 0/10=0 → 进入else分支
    • 0%10=0 → 返回0(正确)
  • 风险:未显式处理num<0的情况(题目要求非负整数)
2. 代码冗余
  • 冗余操作else分支的num%10可简化为num(因num<10时二者等价)
  • 变量冗余:临时变量a非必需
3. 可读性优化
  • 递归条件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%10num 单数字时直接返回更高效
条件可读性 num/10>0num>=10 逻辑更直观

四、递归与迭代方案对比

方案 代码示例 优点 缺点
递归 return num%10 + Digitsum(num/10); 逻辑简洁,直接映射数学定义 栈溢出风险(超大数据)
迭代

题目四: 递归和非递归分别实现求n的阶乘(不考虑溢出的问题)

1.递归方式来实现

代码如下:

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);
}

2.非递归方式来实现:

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);
 }

c语言代码习题——递归习题_第2张图片

题目一见上一篇文章:斐波那契数列
c语言代码习题——递归习题_第3张图片

你可能感兴趣的:(c语言,算法,数据结构)