卢同学的Java笔记_4:常用算法之穷举、递推、递归、分治、概率算法

Hey,我是寒水,一名大二学生,电子商务专业在读,正在学习Java中。我试图将在Java学习中遇到的一些困惑和最终的解答发在这个账号上,希望以此来激励我不要放弃学习!

队列、树、图这三种数据结构我还在慢慢地啃,很多地方都还不是很懂,所以不敢发出来。往后学习了一些基本的算法思想,发现算法思想真的非常迷人,尤其是概率算法和递归算法,我很快也很顺地学完了,写下这篇博客。

这里只包括了五种基本算法,穷举算法递推算法递归算法分治算法概率算法,之后的排序算法和查找算法也正在学习中,相信很快我也能学会啦!

  1. 穷举算法

穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕。若某个情况验证符合题目的全部条件,则为本问题的一个解;若全部情况验证后都不符合题目的全部条件,则本题无解。穷举法也称为枚举法。
穷举算法的基本思想就是从所有可能的情况中搜索正确的答案,所以在使用算法前,需要明确问题的答案的范围,之后使用循环语句和条件判断语句逐步验证候选答案的正确性,从而得到正确答案。
举例为鸡兔同笼问题

package work1;
	import java.util.*;
	public class 穷举 {
		static void chickenAndRabbit(int head,int feet)
		{
			int chicken;
			for(chicken=0;chicken<head;chicken++)
			{
				if(2*chicken+4*(head-chicken)==feet)
				{
					System.out.printf("共有鸡%d只,兔%d只\n",chicken,head-chicken);
				}
			}
			System.out.println("若无显示,表明无法求解。");
		}
		public static void main(String[] args)
		{
			Scanner input=new Scanner(System.in);
			System.out.print("请输入笼中头数:");
			int head=input.nextInt();
			System.out.print("请输入笼中脚数:");
			int feet=input.nextInt();
			chickenAndRabbit(head, feet);
			input.close();
		}
	}

  1. 递推算法

递推算法是一种简单的算法,即通过已知条件,利用特定关系得出中间推论,直至得到结果的算法。递推算法分为顺推和逆推两种。
递推的执行过程如下
(1)根据已知结果和关系,求解中间结果。
(2)判定是否达到要求,如果没有达到,则继续求解中间结果,并不断前推,直至找到正确答案。
举例为《算盘书》中的斐波那契问题。


package work1;
import java.util.Scanner;

	public class fibonacci{
		public static int Fibonacci(int n){
			int a1,a2;
			if(n==1||n==2) {
				return 1;
			}
			else {
				a1=Fibonacci(n-1);
				a2=Fibonacci(n-2);
				return a1+a2;
			}
	}
		

			public static void main(String[] args) {
				System.out.println("Please input the month you want to know!");
				Scanner input=new Scanner(System.in);
				int month=input.nextInt();
				month=Fibonacci(month);
				System.out.println(month);
				input.close();
			}
		}
	
  1. 递归算法

递归算法即在从程序中不断反复调用自身来达到解决问题的方法,重点是调用自身。使用递归算法往往可以简化代码编写,提高程序可读性。他包括了

  • 直接递归,即调用方法本身。
  • 间接递归,即间接地调用一个方法,但用的不多。
    举例问题为求阶乘问题
package work1;
import java.util.*;
public class 递归 {
	static int jiecheng(int n) {
		int m=n-1;
		if(n==1)
		{
			return 1;
		}
		else
		{
			return n*jiecheng(m);
		}
	}
	
	public static void main(String[] args) {
		System.out.println("input the num you want to check.");
		Scanner input=new Scanner (System.in);
		int a= input.nextInt();
		System.out.printf("the num is %d",jiecheng(a));
	}
}

值得一提的是,由于递推与递归的名称相似性,我暂时的理解是,递推是从已知条件出发,不停地向未知前推,直到求解需要的答案。而递归则是已知条件的情况下,疯狂调用已知条件使问题变为原有问题的子问题,从而求解。
·
前者由简入难,后者由难入简。

  1. 分治算法

分治算法的基本思想是将一个计算复杂的问题分为规模较小,计算简单的问题,从而解决问题。步骤为:
(1)对于简单的问题,直接求解。
(2)将困难的问题分为若干小问题,互不干涉。
(3)递归解决小问题。
(4)将小问题的解合并从而得到问题的解。
举例为寻找假币问题——一堆硬币中存在一个较轻的假币,通过对半称量的方式寻找假币。

package work1;
import java.util.*;

public class fenzhi {
	static int Falsecoin(int coin[],int begin,int last)
	{
		int sum1=1,sum2=1,sum3=1;
		if(begin+1==last)
		{
			if(coin[begin]<coin[last])
			{
				return begin+1;
			}
			else
			{
				return last+1;
			}
		}
		if((last-begin+1)%2==0)
		{
			for(int i=begin;i<=begin+(last-begin)/2;i++)
			{
				sum1+=coin[i];
			}
			for(int i=begin+(last-begin)/2+1;i<=last;i++)
			{
				sum2+=coin[i];
			}
			if(sum1<sum2)
			{
				return Falsecoin(coin, begin, begin+(last-begin)/2);		
			}
			else
			{
				return Falsecoin(coin, begin+(last-begin)/2+1, last);	
			}
		}
		else
		{
			for(int i=begin;i<begin+(last-begin)/2-1;i++)
			{
				sum1+=coin[i];
			}
			for(int i=begin+(last-begin)/2;i<last;i++)
			{
				sum2+=coin[i];
			}
			sum3=coin[last];
			if(sum1+sum3==sum2+sum3)
			{
				return last;
			}
			if(sum1<sum2)
			{
				return Falsecoin(coin, begin, begin+(last-begin)/2-1); 
			}
			if(sum1>sum2)
			{
				return Falsecoin(coin, begin+(last-begin)/2, last-1);		  
			}
		}
		return 0;
	}
	
	public static void main(String[] args)
	{
		int number=1;
		System.out.print("请输入一共有多少个硬币:");
		Scanner input=new Scanner(System.in);
		int []coins=new int[number=input.nextInt()];
		System.out.println("依次输入硬币的质量");
		for(int i=0;i<number;i++)
		{
			coins[i]=input.nextInt();
		}
		int num=Falsecoin(coins,0, number-1);
		System.out.printf("假币在第%d个位置",num);
		input.close();
	}
}

  1. 概率算法

概率算法依照统计的思路来思考问题,往往无法得到准确的答案,但很多数学问题无法或者很难进行计算解析,这时便需要使用概率算法来求出近似值。它的顺序包括:
(1)将问题转化为几何图形,该图形面积易求,问题结果往往是其中某一部分的面积。
(2)向图形随机撒点。
(3)统计落在所求面积内的点数和面积外的点数。
(4)判断是否为所求精度内,是则输出近似值。
举例问题为求圆周率PI:

package work1;
import java.util.*;

public class gailv {
	static double PI(int n){
		double x,y;
		int num=0;
		for(int i=1;i<n;i++)
		{
			x=Math.random();
			y=Math.random();
			if((x*x+y*y)<=1)
			{
				num++;
			}
		}
		double PI=4.0*num/n;
		return PI;
		}
	
	public static void main(String[] args){
		System.out.println("请输入点的数量以计算PI,数量越多准确性越高。");
		Scanner input=new Scanner(System.in);
		int a=input.nextInt();
		double b=PI(a);
		System.out.print("PI的值为:"+b);
	}
}

感谢阅读,欢迎订阅!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值