package com.patience.interview.huawei;
import java.util.Scanner;
/**
* 将真分数分解为埃及分数
* @author Green.Gee
* @date 2022/12/7 15:02
* @email green.gee.lu@gmail.com
*/
public class MathSolve1 {
/**
* 分子为1的分数称为埃及分数
* 分子比分母小的分数,叫做真分数
* 将真分数分解为埃及分数
* 8/11 = 1/2+1/5+1/55+1/110
* @param args
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNext()){
String s=in.next();
egyptAnalyse(s);
}
in.close();
}
/**
* 以上其实是数学家斐波那契提出的一种求解埃及分数的贪心算法,准确的算法表述应该是这样的:
* 设某个真分数的分子为a,分母为b;
* 把b除以a的商部分加1后的值作为埃及分数的某一个分母c;
* 将a乘以c再减去b,作为新的a;
* 将b乘以c,得到新的b;
* 如果a大于1且能整除b,则最后一个分母为b/a;算法结束;
* 或者,如果a等于1,则,最后一个分母为b;算法结束;
* 否则重复上面的步骤。
*
* @TODO 备注:事实上,后面判断a是否大于1和a是否等于1的两个判断可以合在一起,
* 及判断b%a是否等于0,最后一个分母为b/a,显然是正确的。
*/
private static void egyptAnalyse(String s) {
String[] parts=s.split("/");
int a=Integer.parseInt(parts[0]);//分子
int b=Integer.parseInt(parts[1]);//分母
StringBuilder sb=new StringBuilder();
int c;
while (a != 1) {
//类似3/110的情况,这里加着方便快速得出结果
//虽然没有这个if条件判断,也能得出,但是会慢很多,而且埃及分解结果不唯一,加了该判断结果会更快
if (b % (a - 1) == 0) {
sb.append("1/").append(b / (a - 1)).append('+');
a = 1;
} else {
c = b / a + 1; //重要点
sb.append("1/").append(c).append('+');
a = a * c - b; // a/b-1/c=(a*c-b)/(b*c),所以分子a = a * c - b;
b = c * b; // 分母b = c * b;
if (b % a == 0) {
b = b / a;
a = 1;//直接跳出循环
}
}
}
sb.append("1/").append(b);
System.out.println(sb.toString());
}
}
03-13
1593
