递归算法案例分析

简介: 一、递归练习(斐波那契数列) 不死神兔 故事得从西元1202年说起,话说有一位意大利青年,名叫斐波那契。 在他的一部著作中提出了一个有趣的问题:假设一对刚出生的小兔一个月后就能长成大兔,再过一个月就能生下一对小兔,并且此后每个月都生一对小兔,一年内没有发生死亡, 问:一对刚出生的兔子,一年内繁殖成多少对兔子?算法分析: 1 1 2 3 5 8 13

一、递归练习(斐波那契数列)

  • 不死神兔
  • 故事得从西元1202年说起,话说有一位意大利青年,名叫斐波那契。
  • 在他的一部著作中提出了一个有趣的问题:假设一对刚出生的小兔一个月后就能长成大兔,再过一个月就能生下一对小兔,并且此后每个月都生一对小兔,一年内没有发生死亡,
  • 问:一对刚出生的兔子,一年内繁殖成多少对兔子?
算法分析:
  • 1 1 2 3 5 8 13
  • 第一个月一对小兔子 1
  • 第二个月一对大兔子 1
  • 第三个月一对大兔子生了一对小兔子 2
  • 第四个月一对大兔子生了一对小兔子
  • 一对小兔子长成大兔子 3
  • 第五个月两对大兔子生两对小兔子
  • 一对小兔子长成大兔子 5

我们首先可以用非递归的方法来做这个题目
private static void demo1() {
		// 方法一
		// 用数组做不死神兔
		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]);
	}


然后我们可以用第递归来做,
	// 第2种方法:用递归求斐波那契数列
	/*
	 * 分析: 1=fun(1) 1=fun(2) 2=fun(1)+fun(2) 3=fun(2)+fun(3)
	 */
	public static int fun(int num) {
		if (num == 1 || num == 2) {
			return 1;
		} else {
			return fun(num - 2) + fun(num - 1);
		}
	}


二、集合练习(约瑟夫环)
  • 幸运数字
/*
	 * 返回值类型为int
	 * 
	 */
	public static int getLuckNum(int num){
		//创建集合1到num的对象
		ArrayList<Integer>  list=new ArrayList<>();
		for(int i=1;i<=num;i++){
			list.add(i);    //存储到集合中
		}
		int count=1;    //只要是3的倍数就remove掉
		for(int i=0;list.size()!=1;i++){  //只要集合中人数超过1,就要不断的杀
			if(i==list.size()){
				i=0;         //如果i增长到集合最大的索引+1时,就重新归0
			}
			if(count%3==0){
				list.remove(i--);
				
			}
			count++;
					
		}
		return list.get(0);
	}


三、
递归练习(1000的阶乘所有零和尾部零的个数)
当然,如果我们直接使用以下方法来做的话是不可行的
/*
		 * int result=1; //这里要从1开始,不能从0开始,因为任何数乘0都为0 
		 * for(int i=1;i<=1000;i++){
		 * 		result=result*i; 
		 * } 
		 * 	System.out.println(result);
		 * //此方法不能使用,因为这样计算的值(1000的阶乘)超出int的取值范围了
		 */

所以我们需要这样做,先去求出1000的阶乘,然后再去统计有多少个0.

// 求出1000的阶乘
		BigInteger bi1 = new BigInteger("1");
		for (int i = 1; i <= 1000; i++) {
			BigInteger bi2 = new BigInteger(i + "");// 转换为字符串类型的
			bi1 = bi1.multiply(bi2); // 将bi1与bi2相乘的结果赋值给bi1
		}

// 求出尾部所有的0
	private static void demo2(BigInteger bi1) {
		String str=bi1.toString();
		StringBuilder sb=new StringBuilder(str);
		str=sb.reverse().toString();  //链式编程
		int count=0;
		for(int i=0;i<str.length();i++){
			if('0'!=str.charAt(i)){
				break;
			}else{
				count++;
			}
		}
		System.out.println(count);
	}

	// 求出所有的0
	private static void demo1(BigInteger bi1) {
		String str = bi1.toString();// 获取字符串表现形式
		int count = 0;
		for (int i = 0; i < str.length(); i++) {
			if ('0' == str.charAt(i)) { // 如果字符串中出现了0则计数器加1
				count++;
			}
		}
		System.out.println(count);
	}

那么如果我们用递归来做的话,这个问题就会非常简单了,

//求出1000的阶乘所有零和尾部零的个数,用递归做
public class h {

	public static void main(String[] args) {
		System.out.println(fun(1000));

	}
	public static int fun(int num){
		
		if(num>0 && num<5){
			return 0;
		}else{
			return num/5 + fun(num/5);
		}
	}
}

File类递归练习(统计该文件夹大小)
需求:,从键盘接收一个文件夹路径,统计该文件夹大小

</pre><pre name="code" class="java">/*
	 * 从键盘接收一个文件夹路径
	 * 定义一个无限循环
	 * 将键盘录入的结果存储并封装成File对象
	 * 对File对象判断
	 * 将文件夹路径对象返回
	 * 
	 * 
	 * 统计该文件夹大小
	 * 1、定义一个求和变量
	 * 2、获取该文件夹下所有的文件和文件夹listFiles();
	 * 3、遍历数组
	 * 4、判断是文件就计算大小并累加
	 * 5、判断是文件夹就递归调用
	 * 
	 * 
	 */

	public static void main(String[] args){
		File dir=getDir();
		System.out.println(getFileLength(dir));
	}
	
	public static File getDir(){
		Scanner sc=new Scanner(System.in);
		System.out.println("请输入一个文件夹路径");
		while(true){
			String line=sc.nextLine();
			File dir=new File(line);
			if(!dir.exists()){
				System.out.println("目录不存在");
			}else if(dir.isFile()){
				System.out.println();
			}else{
				return dir;
			}	
		}
	
	}
	
	public static long getFileLength(File dir){
		long len=0;
		File[] files=dir.listFiles();
		for(File file :files){
			if(file.isFile()){
				len=len+file.length();
			}else{
				len=len+getFileLength(file);
			}
		}
		return len;
	}




File类递归练习(删除该文件夹)
需求:,从键盘接收一个文件夹路径,删除该文件夹

分析:

/*
	 * 1、获取该文件夹下的所有文件和文件夹
	 * 2、遍历数组
	 * 3、判断是文件直接删除
	 * 4、如果是文件夹,递归调用
	 * 5、循环结束后,把控文件夹删除
	 * 
	 */

	public static void main(String[] args) {
		File dir=a.getDir();
		deleteFile(dir);

	}
	public static void deleteFile(File dir){
		File[] subFiles=dir.listFiles();
		for(File file:subFiles){
			if(file.isFile()){
				file.delete();
			}else{
				deleteFile(file);
			}
		}
		//循环结束后把文件夹删除掉
		dir.delete();
	}




File类递归练习(拷贝)
需求,从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中

/*
	 * 1、在目标文件夹中创建原文件夹
	 * 2、获取原文件夹中所有的文件和文件夹,存储在File数组中
	 * 3、遍历数组
	 * 4、如果是文件就用io流读写
	 * 5、如果是文件夹就递归调用
	 * 
	 */
	public static void main(String[] args) throws IOException {
		File src=a.getDir();
		File dest=a.getDir();
		if(src.equals(dest)){
			System.out.println("目录文件夹是源文件夹的子文件夹");
		}else{
			copy(src,dest);
		}
	}

	public static void copy(File src, File dest) throws IOException {
		File newDir=new File(dest,src.getName());
		newDir.mkdir();
		File[] subFiles=src.listFiles();
		for (File file : subFiles) {
			if(file.isFile()){
				BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
				BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File(newDir,file.getName())));
				int b;
				while((b=bis.read())!=-1){
					bos.write(b);
				}
				bis.close();
				bos.close();
			}else{
				//如果是文件夹就递归调用
				copy(file,newDir);
			}
		}
		
	}




File类递归练习(按层级打印)
* 要求:,从键盘接收一个文件夹路径,把文件夹中的所有文件以及文件夹的名字按层级打印,

/*
	 * 1、获取所有文件和文件夹,返回的File数组
	 * 2、遍历数组
	 * 3、无论是文件还是文件夹,都需要直接打印
	 * 4、如果是文件夹,递归调用
	 * 
	 */
	public static void main(String[] args) {
		File dir=a.getDir();
		printLev(dir,0);
		
	}

	public static void printLev(File dir,int level) {
		File[] subFiles=dir.listFiles();
		for (File file : subFiles) {
			for(int i=0;i<=level;i++){
				System.out.print("\t");
			}
			System.out.println(file);
			if(file.isDirectory()){
				printLev(file,level+1);
			}
		}
		
	}






目录
相关文章
|
25天前
|
人工智能 编解码 算法
DeepSeek加持的通义灵码2.0 AI程序员实战案例:助力嵌入式开发中的算法生成革新
本文介绍了通义灵码2.0 AI程序员在嵌入式开发中的实战应用。通过安装VS Code插件并登录阿里云账号,用户可切换至DeepSeek V3模型,利用其强大的代码生成能力。实战案例中,AI程序员根据自然语言描述快速生成了C语言的base64编解码算法,包括源代码、头文件、测试代码和CMake编译脚本。即使在编译错误和需求迭代的情况下,AI程序员也能迅速分析问题并修复代码,最终成功实现功能。作者认为,通义灵码2.0显著提升了开发效率,打破了编程语言限制,是AI编程从辅助工具向工程级协同开发转变的重要标志,值得开发者广泛使用。
7939 68
DeepSeek加持的通义灵码2.0 AI程序员实战案例:助力嵌入式开发中的算法生成革新
|
6天前
|
供应链 算法 搜索推荐
从公布的前十一批其他算法备案通过名单分析
2025年3月12日,国家网信办发布算法备案信息,深度合成算法通过395款,其他算法45款。前10次备案中,深度合成算法累计3234款,其他类别647款。个性化推送类占比49%,涵盖电商、资讯、视频推荐;检索过滤类占31.53%,用于搜索优化和内容安全;调度决策类占9.12%,集中在物流配送等;排序精选类占8.81%,生成合成类占1.55%。应用领域包括电商、社交媒体、物流、金融、医疗等,互联网科技企业主导,技术向垂直行业渗透,内容安全和多模态技术成新增长点。未来大模型检索和多模态生成或成重点。
从公布的前十一批其他算法备案通过名单分析
|
7天前
|
人工智能 自然语言处理 供应链
从第十批算法备案通过名单中分析算法的属地占比、行业及应用情况
2025年3月12日,国家网信办公布第十批深度合成算法通过名单,共395款。主要分布在广东、北京、上海、浙江等地,占比超80%,涵盖智能对话、图像生成、文本生成等多行业。典型应用包括医疗、教育、金融等领域,如觅健医疗内容生成算法、匠邦AI智能生成合成算法等。服务角色以面向用户为主,技术趋势为多模态融合与垂直领域专业化。
|
5天前
|
自然语言处理 算法 安全
境内深度合成服务算法备案通过名单分析报告
本报告基于《境内深度合成服务算法备案通过名单》,分析了2023年6月至2025年3月公布的10批备案数据,涵盖属地分布、行业应用及产品形式等多个维度。报告显示,深度合成算法主要集中于经济发达地区,如北京、广东、上海等地,涉及教育、医疗、金融、娱乐等多行业。未来趋势显示技术将向多模态融合、行业定制化和安全合规方向发展。建议企业加强技术研发、拓展应用场景、关注政策动态,以在深度合成领域抢占先机。此分析旨在为企业提供参考,助力把握技术发展机遇。
境内深度合成服务算法备案通过名单分析报告
|
20天前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
30 3
|
8天前
|
人工智能 自然语言处理 算法
从第九批深度合成备案通过公示名单分析算法备案属地、行业及应用领域占比
2024年12月20日,中央网信办公布第九批深度合成算法名单。分析显示,教育、智能对话、医疗健康和图像生成为核心应用领域。文本生成占比最高(57.56%),涵盖智能客服、法律咨询等;图像/视频生成次之(27.32%),应用于广告设计、影视制作等。北京、广东、浙江等地技术集中度高,多模态融合成未来重点。垂直行业如医疗、教育、金融加速引入AI,提升效率与用户体验。
|
2月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
3月前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
70 6
|
4月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
110 1
|
5月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。