題目描述
分子爲1的分數稱爲埃及分數。現輸入一個真分數(分子比分母小的分數,叫作真分數),請將該分數分解爲埃及分數。如:8/11 = 1/2+1/5+1/55+1/110。
輸入描述
輸入一個真分數,String型
輸出描述
輸出分解後的string
輸入例子
8/11
輸出例子
1/2+1/5+1/55+1/110
算法實現
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
/**
* Declaration: All Rights Reserved !!!
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
while (scanner.hasNext()) {
String real = scanner.next();
// System.out.println(convert(real));
// System.out.println(convert2(real));
System.out.println(convert3(real));
}
scanner.close();
}
/**
* 方法一
* 真分數分解爲埃及分數
* 解題思路
* <p>
* 【貪心算法】
* 設a、b爲互質正整數,a < b 分數a/b 可用如下的步驟分解成若干個單位分數之和:
* 步驟一: 用b 除以a,得商數q1 及餘數r1。(r1=b - a*q1)
* 步驟二:把a/b 記做:a/b=1/(q1+1)+(a-r)/b(q1+1)
* 步驟三:重複步驟2,直到分解完畢
* 3/7=1/3+2/21=1/3+1/11+1/231
* 13/23=1/2+3/46=1/2+1/16+1/368
* 以上實際上是數學家斐波那契提出的一種求解埃及分數的貪心算法,準確的算法表述應該是這樣的:
* 設某個真分數的分子爲a,分母爲b;
* 把b除以a的商部分加1後的值做爲埃及分數的某一個分母c;
* 將a乘以c再減去b,做爲新的a;
* 將b乘以c,獲得新的b;
* 若是a大於1且能整除b,則最後一個分母爲b/a;算法結束;
* 或者,若是a等於1,則,最後一個分母爲b;算法結束;
* 不然重複上面的步驟。
* 備註:事實上,後面判斷a是否大於1和a是否等於1的兩個判斷能夠合在一塊兒,及判斷b%a是否等於0,最後一個分母爲b/a,顯然是正確的。
*
* @param real 真分數
* @return 埃及分數
*/
private static String convert(String real) {
String[] parts = real.split("/");
// 分子
int a = Integer.parseInt(parts[0]);
// 分母
int b = Integer.parseInt(parts[1]);
StringBuilder builder = new StringBuilder(64);
// System.out.print("[1]" + a + "/" + b + ": ");
while (b % a != 0) {
// 求商
int q = b / a;
// 餘數
int r = b % a;
builder.append(1).append('/').append(q + 1).append('+');
a = a - r;
b = b * (q + 1);
}
builder.append(1).append('/').append(b / a);
return builder.toString();
}
/**
* 方法二
* 真分數分解爲埃及分數
* <p>
* 若真分數的分子a能整除分母b,則真分數通過化簡就能夠獲得埃及分數,
* 若真分數的分子不能整除分母,則能夠從原來的分數中分解出一個分母爲b/a+1的埃及分數。
* 用這種方法將剩餘部分反覆分解,最後可獲得結果。
*
* @param real 真分數
* @return 埃及分數
*/
private static String convert2(String real) {
String[] parts = real.split("/");
// 分子
int a = Integer.parseInt(parts[0]);
// 分母
int b = Integer.parseInt(parts[1]);
StringBuilder builder = new StringBuilder(64);
// System.out.print("[2]" + a + "/" + b + ": ");
while (b % a != 0) {
// 分解出一個分母爲b/a+1的埃及分數
int c = b / a + 1;
a = a * c - b;
b = b * c;
builder.append(1).append('/').append(c).append('+');
}
builder.append(1).append('/').append(b / a);
return builder.toString();
}
/**
* 方法三
* 真分數分解爲埃及分數
*
* @param real 真分數
* @return 埃及分數
*/
private static String convert3(String real) {
String[] parts = real.split("/");
// 分子
int a = Integer.parseInt(parts[0]);
// 分母
int b = Integer.parseInt(parts[1]);
StringBuilder builder = new StringBuilder(64);
int c;
while (a != 1) {
if (b % (a - 1) == 0) {
builder.append("1/").append(b / (a - 1)).append('+');
a = 1;
} else {
c = b / a + 1;
builder.append("1/").append(c).append('+');
a = a * c - b;
b = c * b;
if (b % a == 0) {
b = b / a;
a = 1;
}
}
}
builder.append("1/").append(b);
return builder.toString();
}
}