赶鸭子;角谷定理;java实现

  • 题目分析

目的:

  1. 掌握递归程序设计的方法。明确递归的概念,通过对问题的分析,找出递归关系以及递归出口以对问题进行递归结构设计;
  2. 掌握递归程序转换为非递归程序的方法。

要求:

        用递归方法设计下列各题,并给出每道题目的递归出口(递归结束的条件)和递归表达式。同时考虑题目可否设计为非递归方法,如果可以,设计出非递归的算法。

1.一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?

2.角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。

如:输入22,

输出 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

 STEP=16

  • 算法构造:
  1. 赶鸭子:

递归算法函数:duck()=2                                 Village=0

                         duck()=2*(duck(village-1)+1   0<village<8

非递归算法实现:

  1. 角谷定理:

递归算法函数:step()=a            a=1

                         step()=step(a/2)     a%2=0

                         step()=step(a*3+1)   a%2!=0

非递归算法实现:

  • 算法实现
  1. 赶鸭子:

递归实现:

package Duck;

//递归实现
/*village为村庄数
 * sum为鸭子总数
 * num为每经过一个村子卖出的鸭子数
 * */
public class Duck递归 {
	/*递归函数:duck()=2                        village=0
	 *          duck()=2*(duck(village-1)+1)    0<village<8
	 */
	public static int duck(int village) {
		if(village==0)
			return 2;
		else if(village>0)
		    return 2*(duck(village-1)+1);
		return village;
	}
	public static void main(String[] args) {
		int i,num;
		int sum=duck(7);
		System.out.println("总共有"+sum+"只鸭子!");
		for(i=1;i<8;i++) {
			num=sum/2+1;
			sum=sum-num;
			System.out.println("经过第"+i+"个村子时卖出"+num+"只鸭子,还剩下"+sum+"只鸭子");
		}
	}

}

非递归实现:

package Duck;

/*非递归
 * i为村庄数
 * sums为当前村庄所有鸭子总数
 * num为当前村庄卖出鸭子数
 * sum为当前村庄卖出鸭子后所剩鸭子总数*/

public class Duck非递归 {
	public static void main(String[] args) {
		int i,sums,num;
		int sum=2;
		for(i=7;i>0;i--) {						
			sums=(sum+1)*2;
			num=sums-sum;
			System.out.println("经过第"+i+"个村子时卖出"+num+"只鸭子,还剩下"+sum+"只鸭子");
			sum=sums;
		}
		System.out.println("总共有"+sum+"只鸭子!");
	}
}
  1. 角谷定理:

递归实现:

package 角谷定理;

/*角谷定理递归方法
 *  step为经历次数
 * a为输入的自然数*/

import java.util.Scanner;

public class 角谷定理递归 {
	static int step;
	/*递归函数:  step()=a        a=1 
	 *           step()=step(a/2)    a%2=0
	 *           step()=step(a*3+1)   a%2!=0
	 */
		public static int Step(int a) {
			if(a==1)    //输入的自然数为1
			{
				System.out.print(a+" ");
				step++;  
			}
			else if(a%2==0)   //输入的自然数为偶数
			{
				System.out.print(a+" ");
				Step(a/2);    //调用递归方法
				step++;
			}
			else if(a%2!=0)   //输入的自然数为奇数
			{
				System.out.print(a+" ");
				Step(a*3+1);     //调用递归方法
				step++;
			}
			return step;
		}
	public static void main(String[] args)
	{		
		Scanner sc=new Scanner(System.in);
		System.out.print("请输入一个自然数:");
		int a=sc.nextInt();
		sc.close();
		int step=Step(a);
		System.out.println("\n一共经过了"+step+"次");
	}	
}

非递归实现:

package 角谷定理;

import java.util.Scanner;

/*角谷定理非递归方法
 * step为经历次数
 * a为输入的自然数*/

public class 角谷定理非递归{
	static int step;
	public static void main(String[] args) {
		int i;
		Scanner sc=new Scanner(System.in);
		System.out.println("请输入一个自然数:");
		int a=sc.nextInt();
		sc.close();
		while(a>0){
			if(a==1) {
				step++;
				System.out.print(a);
				break;
			}
			else if(a%2==0) {
				step++;
				System.out.print(a+" ");
				a=a/2;
			}
			else {
				step++;
				System.out.print(a+" ");
				a=a*3+1;
			}
		}
		System.out.println("\n一共经历了"+step+"次");
	}

}
  • 调试、测试及运行结果
  1. 赶鸭子调试:

赶鸭子运行结果:

2. 角谷定理调试:

角谷定理运行结果:

  • 经验归纳

1.  一开始在duck()递归函数中只在if语句中返回了值,在函数后没有返回形参,导致错误。

2. 在调试过程进入递归函数之中,一步步观察数值变化,对递归函数算法思路更加清楚。

3. 在duck非递归函数中将村庄数倒着输出,每一步输出后,将当前村庄鸭子总数nums作为上一个村庄卖出鸭子剩余数sum,直到第一个村庄后,直接输出sum即可,开始在循环外将sum与卖出鸭子数num相加作为鸭子总数,导致结果错误。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值