递归算法案例分析

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

  • 不死神兔
  • 故事得从西元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);
			}
		}

	}
时间: 2024-08-07 20:12:30

递归算法案例分析的相关文章

案例分析:如何将免费社区转化为成功的商业模式

社区 Nisan Gabbay注:非常高兴本周的案例分析出自Startup Review的读者Kempton Lam. Kempton是一位管理咨询师,专于创业指导,您可以查看Kempton的背景及博客.Kempton采用了和我相同的案例分析流程,作为编辑,我的工作是确保其与Startup Review保持格式上的一致.如果你有意成为Startup Review的嘉宾作者,请与我联系. 为什么研究这个案例 iStockphoto既是一个摄影师社区,也是一个高质低价的庞大图片库.到2006年10月

Digg&amp;nbsp;案例分析:为什么技术人群是重要的用户

一直觉得Digg是我错过的了一个Web2.0应用,想去研究研究一下,感谢丁丁提供的译文! Digg 案例分析:为什么技术人群是重要的用户原文作者:Nisan Gabbay***:雷声大雨点大原文链接:Digg Case Study: Why techies are an important audience原文发表时间:2006年10月15日 为什么做这个案例分析从2004年12月面世至今,Digg已经成为Web2.0的成功典型.Digg是一个提供新闻内容的网站,它一反传统的层层审核的编辑制度.

广场舞案例分析深入思考二:别样冲突

前面对于Robin广场舞案例从我个人的角度作了深入思考,可能都是一些基础的技巧,但是运用到全面的SEO工作当中还是相当不错的一些技巧,尤其是对没有形成体系的朋友显得尤为重要.最近在不少群里面见到有些朋友认为SEO很简单,个人还是有点担忧,因为SEO真的不是那么简单,而且要真正的学好SEO,这里指的不仅仅是执行的SEO,而是要真正要建立良好的SEO知识结构体系和SEO全局观的SEO. 当然,这两个问题并不是今天我要跟大家谈的想法,后面如果有机会可以跟大家多探讨探讨.今天我要跟大家交流的依然是关于广

案例分析:老张的搬家公司(4)

<老张的搬家公司>第三篇中,我觉得老张很难应用百度凤巢来推广自己的业务,主要原因在于竞争成本.对此,天岸提出了不同看法. 天岸提出的第一点:"除去营销因素之外,有没有考虑到运营因素呢?也许这些出高价的搬家公司的利润很高呢(价格高,相对成本低)?那么理所当然的,点击成本和折算后的转化成本(如果他们有计算的话)对于他们来说是没有多少影响的.本身竞争优势的缺陷也是限制老张们使用更好的营销方法的因素之一吧." 因为这个问题非常好,所以我又舍不得在直接回复了,还是拉出来再成一篇. 老

案例分析:在谈网络公司关键词提升方案

之前荣超帮助朋友分析了一个站点案例分析:一套网络公司网站排名方案那时候好像是5.8号分析的网站,到现在5.16号已经过了8天,早上的时候发现百度昨晚有更新,然后我在去看排名的时候发现排名有部分不错,但是还是没有挺近首页,那么荣超今天在继续看看这个站点吧 首先我们先开关注一下在8天中排名情况吧: 我们可以看到经过改进网站排名已经出现在百度前100位了,之前是没有一个排名在前100名的,但是现在的排名根本对于根本没有任何作用,毕竟别人搜索不会到后面去看你的站点,所以这次我们主要做的就是如何提高排名,

实战案例分析 一个月指数500排名第一

之前就看见了许多实战案例分析的例子,但大多还是一些理论,并没有细节到每一个动作与步骤.今天,我的站刚好上线一个月.今天关键词排名一跃升为第一.看似偶然的事,实是必然.今天和大家分析新站真正快速排名的奥秘,希望其中有某一些改动,某一些细节可以让大家灵感一现,找到自己网站的优化之道. 这个站域名注册时间是6月28日,7月22号上线,迄今为止刚好1个月时间.凤凰古城,指数是5000-6000.凤凰古城住宿,指数500+.其中的热门度不用我说,大家搜索一下便知.当今天打开电脑时,看到网站已经排名第一,说

水杯SEO:百度快照标题显示不正常的案例分析

百度快照标题显示不正常的案例分析,今天水杯在昨天发现水杯SEO博客也出现了百度快照标题显示不正常,这次不同的是,水杯SEO博客只上线了一个星期,虽然百度收录只收录了网站首页,但是快照在上线当天就更新了,刚开始的快照是8-5号,接下来第二次更新快照星期三晚上8-10号,现在的快照是昨天晚上的8-11号,但是快照更新了,网站标题显示却不正常,这个问题相信也有朋友遇到过,现在水杯来和大家一起分析解决这个问题. 在之前的<案例分析:网站百度快照被删除的原因>中,我们发现电脑知识网的情况也是这样,快照隔

实战案例分析网站排名之第一章

这篇<实战案例分析网站排名之第一章>主要是为了和大家一起分析排在百度搜索结果第一位的网站情况,以实例的方式让大家的分析思路更清晰,现在大部分SEO培训教学中所灌输的潜意识都是以内容为皇.外链为王的理论知识,很多SEO导师都是建议网站应该发布原创内容,可有几个网站能够每天都坚持更新原创内容呢?而网站外部链接也是如此,导师都是建议发布高质量的外部链接,可高质量的外部链接怎么可能那么容易就获得呢?那究竟"内容垃圾"."外部链接质量低"的网站能不能获得良好的排名

百度快速排名之案例分析

百度快速排名之案例分析-(一个医药网站的百度30天优化案例分析)网站名称香草醇.阿魏酸.高哌嗪.酚磺乙胺.羟苯磺酸钙-苏州布莱恩斯国际 :网站域名:http://www.szbles.com 网站在10月份接到优化的任务,11月中旬已经有词香草醇已经到第一名了.大家可以在百度上查的到. 先来分析一下关键词:香草醇百度收录(找到相关结果约2,070,000个)也就是说百度数据在200多万条.应该来说优化的难度不是很大.百度指数查不到关键词的指数可以说是很少人会查这样的词,换句话说只有专业的人士才会