穷举算法:从所有可能情况中搜索正确答案,效率并不高,适用于没有明显规律可循的场合。
执行步骤:
(1)确定所有可能结果范围
(2)对于一种可能的结果,计算其结果
(3)判断结果是否满足要求,不满足搜索下一个可能结果,满足则表示寻找到一个正确答案
例子:鸡兔同笼问题
public class P3_1 {
static int chicken,rabbit;
public static int qiongJu(int head,int foot){
int i,j,re;
re=0;
for( i=0;i<=head;i++){
j=head-i;
if(i*2+j*4==foot){
re=1;
chicken=i;
rabbit=j;
}
}
return re;
}
public static void main(String[] args){
int re,head,foot;
System.out.print("输入头的数量");
Scanner input=new Scanner(System.in);
head=input.nextInt();
System.out.print("输入脚的数量");
foot=input.nextInt();
re=qiongJu(head,foot);
if(re==1){
System.out.println(chicken+","+rabbit);
}else{
System.out.println("无解");
}
}
}
递推算法:根据已有的数据和关系,逐步推导而得的结果,一般有明确的公式可循
执行步骤:
(1)根据已知结果求解中间结果
(2)判断结果是否达到要求,如果没有,继续根据已知结果和关系求解中间结果,如果满足则寻找到正确答案
例子:斐波那契数列
public class P3_2 {
public static int fibonacci(int n){
int t1,t2;
if(n==1||n==2){
return 1;
}
else{
t1=fibonacci(n-1);
t2=fibonacci(n-2);
return t1+t2;
}
}
public static void main(String[] args){
System.out.print("请先输入时间");
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int number=fibonacci(n);
System.out.println("经过"+n+"月时间,共繁殖成"+number+"对兔子");
}
}
递归算法:在程序中不断反复调用自身。待解决的问题能够分解为相同问题的一个子问题,必须使用if语句判断递归结束的条件。
直接递归:在方法中调用方法本身
间接递归:方法a调用方法b,方法b又调用方法a
好处:代码简洁清晰,可读性好
缺点:没有明显地减少代码规模和节省内存空间
例子:求阶乘
public class P3_3 {
static long fact(int n){
if(n<=1){
return 1;
}
else{
return n*fact(n-1);
}
}
public static void main(String[] args){
int i;
System.out.print("请输入要求阶乘的一个整数:");
Scanner input=new Scanner(System.in);
i=input.nextInt();
System.out.print(i+"的阶乘结果为:"+fact(i));
}
}
分治算法:将一个计算复杂的问题分为规模较小,计算简单的小问题求解,然后综合各个小问题,求解问题的最终答案。
步骤:
(1)对于一个规模为N的问题,若该问题容易解决则直接解决
(2)否则将分解为M个规模较小的子问题,这些子问题相互独立,并且与原问题形式相同
(3)递归解决子问题
(4)合并子问题的解
例子:寻找假币,30个硬币,一枚假币,假币比真币轻一点,如何区分假币
分析:初始化,为每个硬币编号,将硬币分为两堆,放在天平的两端;假币在较轻的一堆;再将较轻的一堆分为两堆,重复上述做法;直到剩下两枚硬币
public class P3_4 {
static final int MAXNUM=10;
static int FalseCoin(int coin[],int low,int high)
{
int i,sum1,sum2,sum3;
int re=0;
sum1=sum2=sum3=0;
if(low+1==high)
{
//索引是从0到n-1
if(coin[low]<coin[high]){
re=low+1;
return re;
}else{
re=high+1;
return re;
}
}
if((high-low+1)%2==0){//n为偶数
for(i=low;i<=low+(high-low)/2;i++){
sum1=sum1+coin[i];
}
for(i=low+(high-low)/2+1;i<=high;i++){
sum2=sum2+coin[i];
}
if(sum1>sum2){
re=FalseCoin(coin,low+(high-low)/2+1,high);
return re;
}else if(sum1<sum2){
re=FalseCoin(coin,low,low+(high-low)/2);
return re;
}
else{
}
}
else{
//n为奇数
for(i=low;i<low+(high-low)/2-1;i++){
sum1=sum1+coin[i];
}
for(i=low+(high-low)/2+1;i<=high;i++){
sum2=sum2+coin[i];
}
sum3=sum3+coin[low+(high-low)/2];
if(sum1>sum2){
re=FalseCoin(coin,low+(high-low)/2+1,high);
return re;
}else if(sum1<sum2){
re=FalseCoin(coin,low,low+(high-low)/2-1);
return re;
}else{
}
if(sum1+sum3==sum2+sum3){
re=low+(high-low)/2+1;
return re;
}
}
return re;
}
public static void main(String[] args){
int[] coin=new int[MAXNUM];
int i,n;
int weizhi;
System.out.print("请输入银币总的个数:");
Scanner input=new Scanner(System.in);
n=input.nextInt();
System.out.print("请输入银币的真假:");
for(i=0;i<n;i++){
coin[i]=input.nextInt();
}
weizhi=FalseCoin(coin,0,n-1);
System.out.println("第"+weizhi+"个银币是假的");
}
}