递归程序设计
一.问题描述
- 一个人赶着鸭子去每个村庄旁,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
- 角谷定律:输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3再加1,经过如此有限次运算后,总可以得到自然数1,求经过多少次可得到自然数1。
二.题目分析
- 首先要明白题目中的还剩2只是指在第7个村子卖去鸭子后还剩2 只,所以第n个村庄的鸭子数是第n-1个村庄的剩余鸭子数。用递归算法实现的话,递归出口就是,第8个村庄的鸭子数是2。递归体就是,num=(num/2+1)+left,num=(1+left)*2。用循环的普通方法实现的话,for循环从第7个村庄到第1个村庄,for内循环的语句主要还是计算每个村庄的总鸭子数和卖出鸭子数,同上。
- 角谷定律比第一个要简单点儿。普通的解决办法就是当值不为1时,首先判断是奇数还是偶数,然后分别进行操作,输出每次计算的结果,并将次数加1。用递归算法的话,递归出口是计算的值为1,此时返回总运行次数。递归体就是两个判断奇数偶数的语句和各自的执行操作,然后回调方法本身。
三.算法构造
- 角谷定律递归算法:
public static int calculate(int x) {
if (x == 1) {
System.out.print(x + " ");
return count;
} else {
count++;
System.out.print(x + " ");
if (x % 2 == 0)
x /= 2;
else
x = x * 3 + 1;
calculate(x);
}
return count;
}
2.卖鸭子递归算法:
public static int sellDuck(int v,int num) {
if(v==1) {
System.out.println("共有"+num+"只鸭子");
}
if(v>1) {
v--;
num = (num+1)*2;
int sell = num/2+1;
int left = num-sell;
System.out.println("到达第"+v+"个村庄,共有"+num+"只鸭,卖了"+sell+"只鸭,剩下"+left+"只鸭");
sellDuck(v,num);
}
return num;
}
四.算法实现
-
角谷定律
(1)递归算法
package 角谷定律;
import java.util.Scanner;
public class 角谷定律1 {
public static void main(String[] args) {
Scanner input = new Scanne