您的位置:首页 > 其它

贪心法解埃及分数问题

2017-05-24 22:04 197 查看

问题描述:

  古埃及人只用分子分子为1的分数,在表示一个真分数时(分子<分母),将其分解为若干个埃及分数之和,例如7/8=1/2+1/3+1/24.要尽可能用少的埃及分数表示一个真分数的结果。

 

算法技术介绍:

     贪心法解题介绍

     其实以下的两种求解都是贪心法,只不过第一种在一个数学方法上显得有些笨拙。这种求解——找与当前分数最近的埃及分数,本来就很贪心。

 

问题思路:

    在这里要明确一个概念,就是要尽可能用少的埃及分数表示一个真分数。

    思路一:

    因此我们就直接找与当前分数最近的埃及分数,若用一般的方法来求解这个问题的话,我们的思路是这样的:

    当前的a/b,首先找比较1/i(i=2)和它的大小--------(1)

    若a/b>1/i,则做
4000
差并赋给a/b,1/i即使第一个埃及分数,保存结果,i++-----------(2)

    若小于1/i,直接找下一个埃及分数,即i++,再继续跳转至(1)------------(3)

    这种方法是逐一地从最大的一个分数开始比较,找到比他小的第一个埃及分数,然后更新这个分数的值,继续寻找。

    在这里要注意几个细节,埃及分数的结果不需要用二维数组保存,直接用一维数组即可(分子都是一)

然后呢,根据您的循环的设置,不要忘了最后的一个埃及分数是做差后您的结果。

 

   思路二

    和上面的处理差不多,只是那个i的取值更加精确了一点。

    根据一个除法以及的规律,我们可以发现,每一次最大的那个埃及分数是分母除以分子再加一的一个结果,形象化表示:

    真分数A/B  除数C 余数D  最接近当前分数的埃及分数的分母:r

    B/A=C余D   等价于   A=B*C+D    

    r=B/A+1

 

    具体的处理和上面相同,就不再多叙述了,下面看算法是如何实现的。

代码实现:

import java.nio.channels.FileChannel.MapMode;
import java.util.Scanner;
import java.util.Vector;

public class Egypt {

public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
int choice;
int fenzi;
int fenmu;

do{
System.out.println("----------埃及分数------------");
System.out.println("1.蛮力法");
System.out.println("2.贪心法");
System.out.println("0.退出");
System.out.print("请输入您的选择:");
choice=in.nextInt();
switch(choice)
{
case 1:
System.out.print("请输入真分数的分子和分母:");
fenzi=in.nextInt();
fenmu=in.nextInt();
int[] resultVH=EgyptVeryHard(fenzi,fenmu);
PrintResult(resultVH);
break;
case 2:
System.out.print("请输入真分数的分子和分母:");
fenzi=in.nextInt();
fenmu=in.nextInt();
int[] resultGy=EgyptGreedy(fenzi, fenmu);
PrintResult(resultGy);
break;
case 0:
System.out.println("欢迎您的使用~");
break;
default:
System.out.println("您的输入有误,请重新输入!!!");
}
System.out.println();
}while(choice!=0);

}

//蛮力法求解埃及分数,结果和贪心法一样
public static int[] EgyptVeryHard(int fenzi, int fenmu)
{
int i=2;
int[]  result=new int[fenmu];
int count = 0;
while(fenzi!=1)
{
//如果当前的分数比1/r大,则做差,否则和下一个比较
if(fenzi*i>fenmu)
{
//做差
fenzi=fenzi*i-fenmu;
fenmu=fenmu*i;

//约分
int same=getSame(fenmu,fenzi);
fenzi=fenzi/same;
fenmu=fenmu/same;

result[count]=i;count++;
i++;
}

else
i++;
}

//将最后的分母加入
result[count]=fenmu;
return result;
}

//贪心法求解埃及分数
public  static int[] EgyptGreedy(int fenzi,int fenmu)
{
//用一个二维数组保存结果,最大是分母个数那么多个结果
int[] result=new int[fenmu];

int r;
int count=0;
do{
r=fenmu/fenzi+1;
result[count]=r;count++;

//分数与1/r做差,并保存结果
fenzi=fenzi*r-1*fenmu;
fenmu=fenmu*r;

//将做差后的结果约分
int same=getSame(fenmu,fenzi);
fenzi=fenzi/same;
fenmu=fenmu/same;
}while(fenzi!=1);

//将约分最后的一个结果保存
result[count]=fenmu;
return result;
}

//传入分母和分子,返回他们的最大公约数
public static  int getSame(int a, int b)
{
int r=a%b;
while(r!=0)
{
a=b;
b=r;
r=a%b;
}
return b;
}

//打印结果
private static void PrintResult(int[] result)
{
int number=result.length;
System.out.println("以下是您埃及分数的结果:");
for(int i=0;i<number;i++)
{
if(result[i]!=0)
System.out.println("1/"+result[i]+"  ");
}
}
}

运行效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: