一、题目分析
(一)、赶鸭子问题
1、题目要求
2、具体分析
(二)、角谷定理
1、题目要求
格式如:
输入: 22 输出: 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 STEP=16 2、具体分析
二、算法构造
(一)、赶鸭子问题
1、递归算法
以天数键flag为递归出口判断点,flag也为卖出的天数。
2、非递归算法
通过循环将所卖鸭子数通过天数的变化进行依次迭代。循环变量即为买鸭子的天数,直至循环结束所求问题也结束。
(二)、角谷定理
1、递归算法
将输入的值value设置为递归出口。
2、非递归算法
同“赶鸭子问题”相同,通过循环将只进行依次迭代,直至该值变为1,循环结束。
三、算法实现
(一)、赶鸭子问题
public class GanYaZi { private static int flag = 0; public static void main(String[] args) { System.out.println("递归方式求解答案"); System.out.println("---------------------------------------------"); gan_dg(2); System.out.println("---------------------------------------------"); System.out.println("非递归方式求解答案"); System.out.println("---------------------------------------------"); gan_fdg(2); System.out.println("---------------------------------------------"); } /** * 方法public static int gan_dg(int begin)递归方式求解 * @param begin 最后一天所卖的鸭子数 * @return 返回前一天所卖鸭子数 * */ public static int gan_dg(int begin) { flag ++; //当flag增加到8的时候就不用求鸭子个数,因为只卖7天,此时的begin即为所有鸭子量 if(flag == 8) { System.out.println("一共有 " + begin + "只鸭子"); flag = 0; return begin; } else { System.out.print("第" + (8 - flag) + "天卖了"); System.out.println(begin + "只鸭子。"); System.out.println(); //当flag小于等于7的时候返回begin * 2为前一天所卖的鸭子总数 return gan_dg(begin * 2); } } /** * 方法public static void gan_fdg(int begin)非递归方式求解 * @param begin 最后一天所卖鸭子数 * */ public static void gan_fdg(int begin) { //当flag(天数)小于7(从0开始)时让begin * 2 do { System.out.print("第" + (7 - flag) + "天卖了"); System.out.println(begin + "只鸭子。"); System.out.println(); begin *= 2; flag ++; } while (flag < 7); System.out.println("一共有" + begin + "只鸭子。"); flag = 0; } } (二)、角谷定理
import java.util.Scanner; public class JiaoGu { private static int flag = 1; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int value = scanner.nextInt(); System.out.println("递归方式求解答案"); System.out.println("---------------------------------------------"); judge_dg(value); System.out.println("---------------------------------------------"); System.out.println("非递归方式求解答案"); System.out.println("---------------------------------------------"); judge_fdg(value); System.out.println("---------------------------------------------"); } /** * 方法public static int judge_dg(int value)递归方式求解 * @param value 需要求解的数 * @return 最终返回步数 * */ public static int judge_dg(int value) { //当value == 1的时候则需要退出递归 if(value == 1) { System.out.println(value); System.out.println("STEP=" + flag); flag = 0; return flag; } //步数自加 flag ++; System.out.print(value + " "); //根据角谷定理写出的递归式 if((value % 2) == 0) { return judge_dg(value / 2); } else { return judge_dg(value * 3 + 1); } } /** * 方法public static void judge_fdg(int value)非递归方式 * @param value 需要求解的数 * */ public static void judge_fdg(int value) { //当value不为1的时候做 do { System.out.print(value + " "); flag ++; //有角谷定理得到的计算式 if((value % 2) == 0) { value /= 2; } else { value = value * 3 +1; } } while (value != 1); System.out.println(value); System.out.println("STEP=" + flag); flag = 0; } } 四、总结
在一些简单的问题上,对递归表达式的寻找比较容易,而且程序运行的 时间也不会太长。但是在一些比较复杂问题中,采用递归的方式有时候可能时间会比较长。比如说,在求多组多个数最大公约数中,使用欧几里得的递归解决就会比使用非递归方法解决的时间要长。所以对于不同问题需要不同的方法解决。但是使用递归方式解决的一种程序的思维是很好的,可以在一定程度上减少代码重复度。除此之外,递归的思想也能更好的理解一种问题。
文章来源: https://blog.csdn.net/qq_42585466/article/details/90722006