概述
递归
什么是递归,为什么使用递归?
递归就是函数或者方法自己调用自己的过程。在生活中,我们睡觉,闹钟叫我们起床就可以看做一个递归的过程。我们每天睡觉就可以看做成函数的执行。每天都要睡觉,这就是函数的循环执行。只要到时间点我们就会自己去睡觉,这可以看做是自我函数的调用。每个递归函数必须有出口,而这个闹钟就是出口。闹钟一响我们就停止睡觉,干我们自己的事情。人没有闹钟就会睡过头,函数没有出口,函数就会变成死循环。我个人认为递归就是循环的特殊的一种。下面从几个例子来探索递归的奥秘。
不死神兔
故事得从西元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)
这样就可以分析出来这道题主要的意思了
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);//不是出口就继续调用自己
}
使用数组也可以做
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的倍数就拉出去斩了。最后只有一个人活了下来。请问如果一共八个人,这个幸运数字是几?
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,获取所有文件和文件夹,返回的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的阶乘所有零和尾部零的个数
首先不用递归
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.
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);
}
}
总结
递归就是方法或者函数的自我调用,递归一定要有出口,不然就会变成死循环。使用递归可以解决很多循环解决这比较麻烦的问题。
最后
以上就是炙热面包为你收集整理的递归的全部内容,希望文章能够帮你解决递归所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复