一、题目分析
1,赶鸭子
假设此人有n只鸭子,每经过一个村子卖出n/2+1只鸭子,由题意知道经过7个村子后还剩2只鸭子,容易推断经过第8个村子后鸭子将会卖完,此即为递归边界。问题是问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?于是得到一个自变量的递归函数recursiveFun(count),其中count用来记录村子数。
容易得到下面的递归公式:
2,角谷定理
求输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。即如果n是偶数,则除以二(n/2);如果n是奇数,则乘以三再加一,(n3+1);观察这个规律,若要得到自然数1,令n/2=1和n3+1=1,得到2和0,显然0是错误的,那么它的上一个数字一定是2。那么要得到自然数1,只需要对得到的新的数字,重复上面的过程,看这个过程中,是否会出现数字2。如果出现数字2,就可以说,这个迭代过程是不发散的,此即为递归边界。
容易得到下面的递归公式:
二、 算法构造
说明:在画递归算法流程图前,先弄清楚递归流程图怎么画,以下解释答案来自网络
答:和普通函数的流程图没什么区别,就是在调用递归的时候做一个分支出来指向函数开始位置即可
算法流程图:
赶鸭子递归:
赶鸭子非递归:
角谷定理递归:
角谷定理非递归:
三、算法实现程序源代码
赶鸭子:
package indi.sixCharpter_program;
public class Duckquestion {
private static int recursiveFun(int count)//递归算法
{
if(count==8)
return 2;
else
return 2*(recursiveFun(count+1)+1);
}
private static int disrecursiveFun() {//非递归算法
int n=2;//经过七个村子,鸭子数量为2,第八个村子就是0只
int d=0;//用来记录鸭子数
int i=1;
while(i<8){//经过七个村子,循环七次
d=2*(n+1);
System.out.println("第"+(8-i)+"个村子,此人卖出了"+(d/2+1)+"只鸭子,这个人还有鸭子"+(d/2-1));
n=d;
i++;
}
return d;
}
public static void main(String []args) {
for(int i=1;i<8;i++)
System.out.println("第"+i+"个村子,此人卖出了"+(recursiveFun(i)/2+1)+"只鸭子,这个人还有鸭子"+recursiveFun(i)+" ");
System.out.println("刚开始时候此人有鸭子"+disrecursiveFun()+" ");
}
}
角谷定理问题
package indi.sixCharpter_program;
import java.util.Scanner;
public class ValleyAngletheorem {
private static int recursiveFun(int n) {//递归算法
if(n<0)
System.exit(0);
if(n==2) {
System.out.printf("2 step=");//+(++step)
return 1;
}else if(n%2==0) {
System.out.printf(n+" ");
return recursiveFun(n/2)+1;
}
else {
System.out.printf(n+" ");
return recursiveFun(n*3+1)+1;
}
}
private static int disrecursiveFun(int n) {//非递归算法
int step=0;
if(n<0)
System.exit(0);
while(n!=1) {
if(n%2==0){
System.out.printf(n+" ");
n=n/2;
}else {
System.out.printf(n+" ");
n=n*3+1;
}
step++;
}
return step;
}
public static void main(String []args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
System.out.println("递归:");
System.out.println(+recursiveFun(n)+" ");
System.out.println("非递归:");
System.out.println("STEP="+disrecursiveFun(n)+" ");
sc.close();
}
}
四、 调试、测试及运行结果
赶鸭子问题
角谷定理问题
五、经验归纳
递归问题总结:
递归是程序直接或者间接调用自身的过程,递归模型由递归出口和递归体两部分组成,分析问题时主要抽象出递归出口和递归体。递归问题一般分为两大类:一类是比较简单的数学上的递归函数,要求算得一个函数值,只需要将递归函数翻译出来即可。第二类为问题为一些实际的问题,没有统一的规律可循,解决问题的关键为充分的理解问题,发现问题中的已知和隐含条件。根据逻辑关系分析此问题为什么为一个递归问题,并由此得到递归出口和函数递归体,从而使问题得到解决。
编程总结:
此次上机编程方面没有遇到什么难以解决的问题。通过对实际问题的理解分析得到递归公式,将递归公式转化为递归算法,这个步骤是此次上机的重要组成,围绕这样一条思路能够较为清楚的找准目标。递归函数的边界是一个确定的值,函数体是一个递归式,我觉的应该先找到递归边界,在找函数体。以这两个题目看,边界条件可以通过观察计算得到。