递归程序设计方法及实例
来源:互联网 发布:android mac 编辑:程序博客网 时间:2024/05/16 16:16
递归程序设计方法及实例
实例1:一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
//卖鸭子#include<stdio.h>int num(int sum,int day);int main(){int s=num(2,8); //第七天还剩余鸭子2只printf("鸭子总数为%d只\n\n",s);for(int day=1;day<=7;day++) //输出每天卖出的鸭子数{printf("第%d天卖出%d只\n",day,s/2+1);s=s/2-1;}return 0;}int num(int sum,int day){if(day==1)return sum;elsereturn num((sum+1)*2,day-1); //递归计算鸭子数return 0;}
实例2:角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。
如:输入22,
输出 22 11 34 17 52 26 13 40 20 10 5 16 8 4 1
//角谷定理#include<stdio.h>int step;int calculate(int a);int main(){int a; //输入的自然数aprintf("请输入一个自然数:");scanf("%d",&a); calculate(a);return 0;}int calculate(int a){printf("%6d",a);if(a==1)printf("\nStep is %d\n",step+1); else{ if(a%2==0) //输入的自然数为偶数{a=a/2;step++; //每计算一次,step加1calculate(a); //递归调用}else if(a%2!=0) //输入的自然数为奇数{a=a*3+1;step++;calculate(a);}}return 0;}
实例三:电话号码对应的字符组合:在电话或者手机上,一个数字如2对应着字母ABC,7对应着PQRS。那么数字串27所对应的字符的可能组合就有3*4=12种(如AP,BR等)。现在输入一个3到11位长的电话号码,请打印出这个电话号码所对应的字符的所有可能组合和组合数。//电话号码对应字符组合//假设此程序中,0和1对应的英文字母分别为'*','#'//做出此假设的原因是因为0和1没有对应的英文字母#include<stdio.h>#define M 12#define N 30int a[M]; //a[M]存储电话号码每位上的数字char b[28]={'*','#','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; //b[M]存储每个数字对应的不同的英文字母char c[10][10] = { //用字符数组存储每个数字对应的不同英文字母 '*', '#', "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};int i,n;int GroupNum(int x); int main(){printf("请输入电话号码的总位数:");scanf("%d",&n);for(i=0;i<n;i++){printf("请输入电话号码的第%d位:",i+1);scanf("%d",&a[i]);}i=0;printf("此电话号码对应的字符串组合共有%d组\n",GroupNum(1));return 0;}int GroupNum(int x) //求总共组合数{if(i==n)return x;else{if(a[i]==0 || a[i]==1) {x=1*x;i++;GroupNum(x); //递归调用 }else if(a[i]==2 || a[i]==3 || a[i]==4 || a[i]==5 || a[i]==6 || a[i]==8 ) {x=3*x;i++;GroupNum(x);}else{x=4*x;i++;GroupNum(x);}}}
实例4:日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完 后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?//分桔子问题#include<stdio.h>// oldUNum为每个人原有桔子数,getNum为得到的桔子数,n为第几个人int orangeNum(int oldNum,int getNum,int n);int main(){//老大原有240个桔子,得到210个orangeNum(240,210,1);return 0;}int orangeNum(int oldNum,int getNum, int n){int nextGetNum,nextOldNum,m; if(n > 6) //递归出口return 0; else{printf(" 第%d个人原有桔子%d\n",n,oldNum); //输出原先橘子数 if(n == 1) //计算分给下一个人的橘子数nextGetNum = oldNum/(9 - n); else nextGetNum = (oldNum+getNum)/(9-n); nextOldNum = 2520/6* (8-n)/(7-n) - nextGetNum; //下一个人原来的橘子 m = n+1; orangeNum(nextOldNum,nextGetNum,m); }return 0;}
递归程序设计方法总结————常见递归问题的分析与设计
1.卖鸭子问题:这是常见的递归函数问题,求得一个递归函数公式即可。设计函数int num( int sum,int day);其中sum参数返回鸭子的数量,day参数返回第几天。编写递归程序的关键为确定递归出口和递归体。本题递归出口为当day==1时,return sum;递归体为当day!=1时,return num((sum+1)*2,day-1);同时在主函数中输出每天所卖的鸭子数目。
2.角谷定理:本题的设计思路比较简单,仍然为一个递归函数问题。按照题意,输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。得到递归结束出口为a==1;return总步数。递归体为当a==偶数时,自身除以二,并累加步数,返回calculate函数。当a为奇数时,自身乘三加一,并累加步数,返回calculate.
3.电话号码对应的字符组合:首先清楚2,3,4,5,6,8六个数字对应三个英文不同的字母,8,9三个数字对应4个不同的英文字母。由于数字1和0并没有对应的英文字母,所以假设0和1分别对应’*’,’#’,这种假设并不影响最后递归算法的设计。还可以增强程序的健壮性。
计算组合数:需要统计电话号码有几个数字,且每个数字对应几个英文字母。把每个数字对应的英文字母个数乘起来即为组合数。
计算具体的组合:需要统计具体哪几个数字,每个数字具体对应的英文字母是什么。逐一进行组合即可。
4.中村义作教授分桔子问题:这是一个环状互相关联的问题,想到应该使用递归来求解。首先应该分析得到已知和隐含条件。
最后桔子数目相等,则每人为420个。同时老大的身份最特殊,其余的人都是先得到再给出桔子,而老大是先给出后得到,并且最后为420个,由老六分给他210个桔子,则老大原来有240个桔子,老大原先有240个桔子,分出210个桔子,问题的突破口就找到了。设计函数orangeNum(oldNum,getNum,n);三个参数分别为原有桔子数,得到桔子数,和第几个人。将240,210,1三个参数传入后,就开始了递归函数的调用,当n>6时,递归调用结束。
递归问题总结:递归是程序直接或者间接调用自身的过程,递归模型由递归出口和递归体两部分组成,分析问题时主要要抽象出递归出口和递归体。递归问题一般分为两大类:一类是比较简单的数学上的递归函数,要求算得一个函数值,只需要将递归函数翻译出来即可。第二类为问题为一些实际的问题,没有统一的规律可循,解决问题的关键为充分的理解问题,发现问题中的已知和隐含条件。根据逻辑关系分析此问题为什么为一个递归问题,并由此得到递归出口和递归递归体,从而使问题得到解决。这类问题都比较复杂,需要进行大量的练习才能建立这种思维方式。
- 递归程序设计方法及实例
- 递归程序设计的公式化方法
- 递归方法的简单实例
- 程序结构&&程序设计(三) ——递归及递归举例
- 递归程序设计
- 递归程序设计
- 算法导论----<递归插入>及实例
- 递归算法及经典实例----转载啦~
- C语言及程序设计进阶例程-7 递归经典:汉诺塔
- C语言及程序设计进阶例程-5 认识递归
- 《C语言及程序设计》程序阅读——递归函数
- 《C语言及程序设计》实践项目——递归函数
- 《C语言及程序设计》实践参考——递归函数
- C语言及程序设计实践项目-递归和多文件组织
- 【Clojure程序设计】Clojure中转化互递归的方法
- 异常处理、递归和单体程序设计方法1
- 异常处理、递归和单体程序设计方法2
- C++程序设计-第13周递归函数及银行系统程序设计上机实践项目
- 数据库大神的博客
- java File 常用操作
- 学习淘淘商城第六十四课(实现商品详情页面展示)
- Hibernate中运行程序时报错:org.hibernate.hql.internal.ast.QuerySyntaxException: apibasic is not mapped [from
- Android项目通过cmd上传到github
- 递归程序设计方法及实例
- linux学习二-Linux安装
- 找素材模型图片的一些地方
- usaco5.3.4 Big Barn
- jQuery中的DOM操作详细总结
- 常见对象-StringBuffer
- setValue: forKey 和 setObject: forKey 的区别
- C++ Primer 第5版--练习11.12
- 安卓mvp教程