贪心法解埃及分数问题
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]+" "); } } }
运行效果:
相关文章推荐
- 埃及分数问题(迭代加深搜索)
- 算法设计分析: 埃及分数问题
- (算法竞赛入门)埃及分数问题学习笔记
- “埃及分数”问题浅谈对迭代加深搜索的理解
- 埃及分数问题 - 迭代加深搜索经典问题
- 埃及分数问题(剪枝+迭代加深搜索)=>算法竞赛入门经典(第二版)第七章
- 埃及分数问题 - 迭代加深搜索经典问题
- 贪心算法之埃及分数问题(附c++源代码)
- 埃及分数问题-迭代加深搜索与IDA*算法
- UVA - 12558 Egyptian Fractions (HARD version) : 埃及分数问题 IDA*
- 埃及分数问题-IDDFS
- 暴力求解法_隐式图搜索(埃及分数,倒水问题,八数码问题)
- 埃及分数问题 IDA*
- 迭代加深、IDDFS解决埃及分数问题
- IDA* 求解埃及分数问题
- 贪心法之埃及分数
- 贪心算法之埃及分数问题
- 埃及分数问题_迭代加深搜索_C++
- 埃及分数问题 迭代加深搜索(IDDFS)
- 埃及分数问题 【IDA*】