我是靠谱客的博主 炙热面包,这篇文章主要介绍递归,现在分享给大家,希望可以做个参考。

递归

什么是递归,为什么使用递归?

递归就是函数或者方法自己调用自己的过程。在生活中,我们睡觉,闹钟叫我们起床就可以看做一个递归的过程。我们每天睡觉就可以看做成函数的执行。每天都要睡觉,这就是函数的循环执行。只要到时间点我们就会自己去睡觉,这可以看做是自我函数的调用。每个递归函数必须有出口,而这个闹钟就是出口。闹钟一响我们就停止睡觉,干我们自己的事情。人没有闹钟就会睡过头,函数没有出口,函数就会变成死循环。我个人认为递归就是循环的特殊的一种。下面从几个例子来探索递归的奥秘。

不死神兔

故事得从西元1202年说起,话说有一位意大利青年,名叫斐波那契。 在他的一部著作中提出了一个有趣的问题:假设一对刚出生的小兔一个月后就能长成大兔,再过一个月就能生下一对小 兔,并且此后每个月都生一对小兔,一年内没有发生死亡, 问:一对刚出生的兔子,一年内繁殖成多少对兔子?
1 2 3 4 5 6 7 8 月
1 1 2 3 5 8 13 21 对兔子
1 = fun(1)
1 = fun(2)
2 = fun(1) + fun(2)
3 = fun(2) + fun(3)
这样就可以分析出来这道题主要的意思了

复制代码
1
2
3
4
5
6
7
8
public static void main(String[] args) { System.out.println(fun(12));//输出一年繁殖的兔子数 } public static int fun(int num){ if(num==1||num==2)return 1;/方法的出口 else return fun(num-2)+fun(num-1);//不是出口就继续调用自己 }

使用数组也可以做

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) { //数组做不死神兔 int[] arr=new int[12]; arr[0]=1;//第一个月的兔子数 arr[1]=1;//第二月的兔子数 //遍历数组给其他元素赋值 for (int i = 2; i < arr.length; i++) {//从第三个月开始,后面的兔子对数是前面月兔子的和 arr[i]=arr[i-2]+arr[i-1]; } System.out.println(arr[arr.length-1]);//输出1年的兔子对数 }

幸运数字

故事:发生西汉某年的一个早晨,皇上闲来无事,叫来一群犯人,玩一个叫做幸运数字的游戏。就是,所有人围成一个圆圈,如果是3的倍数就拉出去斩了。最后只有一个人活了下来。请问如果一共八个人,这个幸运数字是几?

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static void main(String[] args) { System.out.println(getLucklyNum(8));//输出幸运数字 } /** * 获取幸运数字 1.返回值类型 int 2.参数列表 int num */ private static int getLucklyNum(int num) { // 创建集合存储1到num的对象 ArrayList<Integer> list = new ArrayList<>(); for (int i = 1; i <= num; i++) { list.add(i);//把数字存到集合中 } // 用来数数的,只要是3的倍数就杀人 int count = 1; // 只要集合中人数超过1,就不断的杀 for (int i = 0; list.size() != 1; i++) { // 如果i增长到集合最大的索引+1时 if (i == list.size()) { // 重新归零 i = 0; } if (count % 3 == 0) { // 是3的倍数就杀人 list.remove(i--); } count++; } return list.get(0);//返回最后一个人 }

打印文件夹中的所有文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
需求:从键盘接收一个文件夹路径,把文件夹中的所有文件以及文件夹的名字按层级打印, 例如:把文件夹中的所有文件以及文件夹的名字按层级打印。 分析: 1,获取所有文件和文件夹,返回的File数组 2,遍历数组 3,无论是文件还是文件夹,都需要直接打印 4,如果是文件夹,递归调用 public static void main(String[] args) { File dir=getDir();//获取文件对象 priintLevel(dir,0); } public static File getDir(){ // 1,创建键盘录入对象 Scanner sc = new Scanner(System.in); System.out.println("请输入文件夹路径:"); // 定义个无限循环 如果是文件就输出一句话,是文件夹就返回 while (true) { String str = sc.nextLine(); File dir = new File(str); // 判断文件是否存在 if (!dir.exists()) { System.out.println("你输入的文件夹路径错误!"); } else if (dir.isFile()) { System.out.println("你输入的是文件路径,请重新输入!"); } else { return dir; } } } public static void priintLevel(File dir, int n) { // 获取所有的文件和文件夹 File[] arr = dir.listFiles(); // 判断如果是文件和文件夹就打印文件名 for (File file : arr) { for (int i = 0; i <n; i++) { System.out.println("t"); } //输出文件名 System.out.print(file); //如果是文件夹,调用本身,输出里面的文件名 if(file.isDirectory()){ priintLevel(file,n++); } } }

1000的阶乘所有零和尾部零的个数

首先不用递归
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static void main(String[] args) { demo1();//调用demo1方法 //bi1换成bigInteger,因为1000的阶乘太大 BigInteger bi1=new BigInteger("1"); //循环获取1000的阶乘 for (int i = 1; i < 1000; i++) { BigInteger bi2=new BigInteger(i+""); bi1=bi1.multiply(bi2); } //将bi1转成字符串 String str=bi1.toString(); //放在stringbuilder中 StringBuilder sb=new StringBuilder(str); //反转字符串 str=sb.reverse().toString(); //用来记录0的个数 int count=0; for (int i = 0; i < str.length(); i++) { if('0'!=str.charAt(i)){ //不是0终止循环 break; }else{ //是0 ,计数器++ count++; } } System.out.println("尾部零个数:"+count); } public static void demo1(){ BigInteger bi1=new BigInteger("1"); for (int i = 1; i < 1000; i++) { BigInteger bi2=new BigInteger(i+""); //将bi1与bi2相乘的结果赋值给bi1 bi1=bi1.multiply(bi2); } String str=bi1.toString();//获取字符串表现形式 int count=0; for (int i = 0; i < str.length(); i++) { if('0'==str.charAt(i)){//如果字符串出现0字符 count++; } } System.out.println("全部零的个数:"+count); }

使用递归

分析:

  • 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 … 1000 1000 / 5 = 200
    • 5 * 5 5 * 5 * 2 5 * 5 * 3 5 * 5 * 4 5 * 5 * 5 5 * 5 * 6 200 / 5 = 40
    • 5 * 5 * 5 * 1 5 * 5 * 5 * 2 5 * 5 * 5 * 3 5 * 5 * 5 * 4 5 * 5 * 5 * 5 5 * 5 * 5 * 6 5 * 5 * 5 * 7 5* 5 * 5 * 8
      40 / 5 = 8
      8 / 5 = 1

就是看看1000里面有多少个5,1000阶乘,200是5的倍数,200里面有多少个5,200的阶乘,40是5的倍数,40里有多少个5.最后40的阶乘,8是5的倍数,8的阶乘只有1个5.有几个5就有几个0.

复制代码
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) { System.out.println("尾部有"+fun(1000)+"个零"); } private static int fun(int num) { if(num>0&&num<5){ return 0; }else{ return num/5+fun(num/5); } }

总结

递归就是方法或者函数的自我调用,递归一定要有出口,不然就会变成死循环。使用递归可以解决很多循环解决这比较麻烦的问题。

最后

以上就是炙热面包最近收集整理的关于递归的全部内容,更多相关递归内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部