作者:你我皆为凡人
博客主页:你我皆为凡人的博客
名言警句:时间不会为任何人停留,而事物与人,无时不刻也在变化着。每一个人,也都在不停向前!
觉得博主文章写的不错的话,希望大家三连(✌关注,✌点赞,✌评论),多多支持一下!!
系列作品:
C语言编程刷题篇
经典题型系列
文章目录
目录
文章目录
前言
关于递归的描述错误的是:( )
答案与解析:
根据下面递归函数:调用函数Fun(2),返回值是多少( )
答案与解析:
递归方式实现打印一个整数的每一位
答案与解析:
递归和非递归分别实现求n的阶乘(不考虑溢出的问题)
答案与解析:
递归和非递归分别实现strlen
答案与解析:
字符串反向排列(不是逆序)(递归实现)
答案与解析:
计算一个数的每位之和(递归实现)
答案与解析:
递归实现n的k次方
答案与解析:
递归与非递归计算斐波那契数
总结
前言
关于C语言中的经典题型,你又了解多少呢?凡人在这里给初学者准备了九道关于C语言中递归的题型,让初学者可以很好的练习练习,巩固所学知识
提示:以下是本篇文章正文内容,下面案例可供参考
关于递归的描述错误的是:( )
A.存在限制条件,当满足这个限制条件的时候,递归便不再继续
B.每次递归调用之后越来越接近这个限制条件
C.递归可以无限递归下去
D.递归层次太深,会出现栈溢出现象
答案与解析:
错误的回答是c选项,递归需要两个条件,第一个是必须要有限制条件,每次递归调用时越来越接近这个条件,所以c选项自动排除,不能是死递归,第四个选项,层次太深的话是会出现栈溢出的现象也是对的
根据下面递归函数:调用函数Fun(2),返回值是多少( )
int Fun(int n){ if(n==5) return 2; else return 2*Fun(n+1);}
A.2
B.4
C.8
D.16
答案与解析:
正确答案为D
传参为2,2不等于5,返回2*fun(3),3不等于5,返回2*fun(4),4不等于5,返回2*fun(5),5等于5,返回2,开始回带,2*fun(2)为4,2*fun(4)为8,2*fun(8)为16,所以最后返回的结果为16
递归方式实现打印一个整数的每一位
答案与解析:
用递归的函数的思想是大事化小,并且有一个限制条件,定义一个数,实现打印函数,如果要打印1234这个数, 1234打印4最好打印,可以分为 (123) 4(12)3 4(1)2 3 4
这样就把大事化小了,实现:设定条件,如果大于9,两位数的就拆分,一位数就停下来,,1234/10,调用123,123大于9,123/10,调用12,12大于9,12/10,1,1小于9,开始会带,打印1%10为1,然后2,3,4
#includeint print(int n){if(n>9)print( n / 10);printf("%d", n % 10);return 0;}int main(){int n = 0;scanf("%d", &n);print(n);return 0;}
递归和非递归分别实现求n的阶乘(不考虑溢出的问题)
答案与解析:
求n的阶乘有个公式,如果求5的阶乘,那么相当于5*4的阶乘,但是如果是1的时候就不是了,所以实现:当n小于等于1时,返回1,否则返回n*fac(n-1),这件事递归实现,非递归的方式就是利用循环让每个乘积到ret中,最后返回ret就是和
//递归方式#includeint fac(int n){if (n <= 1)return 1;elsereturn n* fac(n - 1);}int main(){int n = 0;scanf("%d", &n);int ret = fac(n);printf("%d", ret);return 0;}
//迭代方式-非递归#includeint fac(int n){int ret = 1;int i = 0;for (i = 1; i <= n; i++){ret *= i;}return ret;}int main(){int n = 0;scanf("%d", &n);int ret = fac(n);printf("%d", ret);return 0;}
递归和非递归分别实现strlen
答案与解析:
strlen是求字符串的长度,而字符串的长度是由\0来标识的,只要遇到\0就停止,递归实现:如果字符串中不等于\0时,就返回一个1+n+1,因为可以让它指向下一个字符,当等于\0时,返回0,迭代实现,与上面同理,只不过需要定于个ret来接受,如果不等于\0,加加,让字符也加加指向下一个
//递归实现#includeint fac(char* n){if (*n != '\0')return 1 + fac(n + 1);elsereturn 0;}int main(){char arr[] = "abcdef";int ret = fac(arr);printf("%d", ret);return 0;}
//非递归#includeint fac(char* n){int ret = 0;while (*n != '\0'){*n++;ret++;}return ret;}int main(){char arr[] = "abcdef";int ret = fac(arr);printf("%d", ret);return 0;}
字符串反向排列(不是逆序)(递归实现)
内容实现:
编写一个函数 reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列,不是逆序打印。
要求:不能使用C函数库中的字符串操作函数。
比如:
char arr[] = "abcdef";
逆序之后数组的内容变成:fedcba
答案与解析:
这个题目的要求是将字符串反向打印,而不是逆序,而且不能使用c函数中的字符串操作函数
既然要反向,那么需要交换两个字符的位置,然后打印即可,递归实现:求一个字符串“abcdef”,在字符串里的是abcdef\0,大事化小,先把a放到临时变量里,然后把f放到a里,然后把\0放入f中,让bcde\0变成新的字符串,而调用自己的时候需要设定条件,如果中间剩下一个的时候就不需要交换了,所以大于等于2的时候调用
int my_strlen(char* string){int ret = 0;while (*string != '\0'){ret++;string++;}return ret;}void reverse(char* string){int len = my_strlen(string);char tmp = *string;*string = *(string+len-1);*(string + len - 1) = '\0';if (my_strlen(string + 1) >= 2)reverse(string + 1);*(string + len - 1) = tmp;}int main(){char arr[] = "abcdef";reverse(arr);printf("%s", arr);return 0;}
计算一个数的每位之和(递归实现)
内容实现
写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
输入:1729,输出:19
答案与解析:
求一个非负整数每个位数之和,如1729可以分成 172 + 9, 17 + 2 + 9 , 1 +7+2+9,递归实现,如果是一位数的时候,返回这个数,如果大于一位数,返回除以10加上摸10的值,1729/10 172 递归递下去,归回来的每位数加上取余的数
int fac(unsigned int n){if (n > 9){return fac(n / 10) + n % 10;}return n;}int main(){unsigned int n = 0;scanf("%d", &n);int sum = fac(n);printf("%d", sum);return 0;}
递归实现n的k次方
内容实现
编写一个函数实现n的k次方,使用递归实现。
答案与解析:
求一个数的k次方,实际上与pow函数一样,可以发现公式,如果k大于0的时候 为n*pow(n,k-1),如果小于0,为1.0/pow(n,-k),为小数,如果等于0的时候,为1,按照公式照搬就好
double Pow(int n, int k){if (k > 0)return n * Pow(n, k - 1);else if (k < 0)return 1.0/ Pow(n, -k);elsereturn 1;}int main(){int n = 0;int k = 0;scanf("%d%d", &n, &k);double sum = Pow(n, k);printf("%.3lf", sum);return 0;}
递归与非递归计算斐波那契数
内容实现
递归和非递归分别实现求第n个斐波那契数
例如:
输入:5输出:5
输入:10, 输出:55
输入:2, 输出:1
斐波那契数列的特点是前两个为1,从第三个开始为第一个和第二个的和,依次类推可以得到规律,递归实现:如果大于2的时候,返回n-1与n+1的和,这个是从后往前来进行,计算量很大,因为知道n-1的时候需要把前面都知道,有很多重复计算,耗时耗力,不推荐,非递归实现:我们可以从前往后来实现,第一个和第二个都是1,从第三个开始,第一个为a,第二个为b,第三个为a+b,从第一二个没必要开始,从第三个开始计算,为a+b,然后把a赋值为b,b赋值为c来调换,依次循环
int fac(int n){if (n > 2){return fac(n - 1) + fac(n - 2);}return 1;}int main(){int n = 0;scanf("%d", &n);int ret = fac(n);printf("%d", ret);return 0;}
int fac(int n){int a = 1;int b = 1;int c = 1;while (n >= 3){c = a + b;a = b;b = c;n--;}return c;}int main(){int n = 0;scanf("%d", &n);int ret = fac(n);printf("%d", ret);return 0;}
总结
对于函数来说,最重要的莫过于递归了,而想要把递归搞明白,需要大量的练习用来提升自己的思路,只有思路变灵活了,不再那么朦胧,那么这个时候你就发现你慢慢的会了,凡人在这里给大家准备了九道关于递归的一些练习题,大家可以尝试着练习练习,如果觉得凡人讲解的还不错,希望大家多多支持,哪里有不对,也欢迎大家来指正,感谢大家观看!!!