C语言入门基础_函数递归(题目练习及讲解)

练习题1:求n的阶乘(不考虑溢出)

思路:n的阶乘就是 n*(n-1)*(n-1-1)...

自定义一个Fac()函数
当n大于1时,为n*Fac(n-1)
当n等于1时,为1 

代码实现:

int Fac(int n)
{
	if (n > 1)
		return n * Fac(n - 1);
	else 
		return 1;
}

int main()
{
	int n = 0;
	printf("请输入一个正整数n:");
	scanf("%d", &n);
	printf("n的阶乘为:%d",Fac(n));

	return 0;
}

运行结果:

练习题2:求第n个斐波那契数列

思路:1 1 2 3 5 8 13...从第二个数开始,每个数都等于前两个数之和

自定义一个函数Fib()

当n>2时,返回Fib(n-1)+Fib(n-2)

当n=1和n=2时,返回1

代码实现:

int Fib(int n)
{
	if (n > 2)
		return Fib(n - 1) + Fib(n - 2);
	else
		return 1;
}

int main()
{
	int n = 0;
	printf("请输入一个正整数n:");
	scanf("%d", &n);
	printf("斐波那契数列的第%d个数为%d", n, Fib(n));
	return 0;
}

注意:用函数递归写此代码效率太低,当n为一个较大的数字时,会有重复大量的计算,不推荐这么写

用普通的写法可以提高此代码的效率:

int Fib(int n)
{
	int a = 1, b = 1;
	int c = 0;
	if (n > 2)
		while (n > 2)
		{
			c = a + b;
			a = b, b = c;
			n--;
		}
	else
		return 1;
	return c;
}

int main()
{
	int n = 0;
	printf("请输入一个正整数n:");
	scanf("%d", &n);
	printf("斐波那契数列的第%d个数为%d", n, Fib(n));
	return 0;
}

运行结果:

练习题3:编写一个函数reverse_string(char* str)实现字符串字符反向排序

要求:使用函数递归实现,不能使用c函数库的字符串操作函数

思路:

1、假设字符串为"abcdef",可以先求出字符串的长度,设left为字符串的左下标,right为字符串的右下标,即left=0,right=字符串长度,通过交换下标left和下标right的字符来实现。

2、字符串长度用strlen()函数获得,但是题目不允许使用库函数,因此自定义一个my_strlen()函数来实现其功能,具体代码解释在上篇文章。

3、通过此思路,可以得到普通的写法:

int my_strlen(char* str)    //自定义一个函数实现库函数strlen()的功能
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

//普通写法
void reverse_string(char* str)
{
	int left = 0;                    //左下标
	int right = my_strlen(str)-1;    //右下标

	while (left < right)
	{                                //左右下标对应字符交换
		char tmp = str[left];		
		str[left] = str[right];
		str[right] = tmp;
		left++;                      //每次交换后,左下标向右移动,右下标向左移动
		right--;	
	}	
}

int main()
{
	char arr[] = "abcdef";
	reverse_string(arr);
	printf("%s", arr);
	return 0;
}

但是void reverse_string(char* str)部分需要使用函数递归实现

函数递归思路如下:

我们需要处理的字符串是"abcdef"

可用如下思路:

 

 

 因此代码实现如下:

//递归写法:
void reverse_string(char* str)
{
	char tmp = *str;
	int len = my_strlen(str);
	*str = *(str + len - 1);
	*(str + len - 1) = '\0';
	if (my_strlen(str)>=2)
		reverse_string(str + 1);
	*(str + len - 1) = tmp;
}

运行结果:

fedcba

练习题4:输入一个数,得到这个数的每个位数的数之和。例如1234,得到1+2+3+4,为10

思路:

例如输入1234

1234%10得到4        1234/10得到123

123%10得到3        123/10得到12

12%10得到2        12/10得到1

1%10得到1

将其每次得到的值相加即可

代码实现:

int DigitSum(int num)
{
	if (num > 9)
		return num % 10 + DigitSum(num / 10);
	else
		return num;
}

int main()
{
	int num = 0;
	printf("请输入一个数字:");
	scanf("%d", &num);
	int sum = DigitSum(num);
	printf("%d的每个位数的数之和为%d", num, sum);
	return 0;
}

运行结果:

练习题5:编写一个函数实现n的k次方,使用递归实现

思路:

n的k次方等于n乘n的k-1次方

即 定义一个函数Pow(),Pow(n,k)=n*Pow(n,k-1)

代码实现:

double Pow(int n, int k)
{
	if (k > 0)
		return n * Pow(n, k - 1);    //Pow(n,k)=n*Pow(n,k-1)  n的k次方等于n乘n的k-1次方
	else if (k == 0)
		return 1.0;
	else                            //n的k次方,k为负数,得到结果是n的k次方分之一
		return 1.0 / Pow(n, -k);    //输入的k是负数,负负得正,正数k执行k>0的步骤
}
int main()
{
	printf("请输入数字n和k:");
	int n = 0, k = 0;
	scanf("%d %d", &n, &k);
	printf("%d的%d次方为%lf",n,k,Pow(n, k));
	return 0;
}

运行结果:

 

 

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值