### 题目

#### 输出

1. “[N, D]”
2. 如果结果可以被整除，则返回整数：”N”
3. 如果输入为空，或者不合法，返回null

#### 输出样例

[ [1, 2], [1, 3], [1, 4] ] –> [13, 12]

#### 代码模板

 `12345` ``````public class SumFractions { public static String sumFracts(int[][] input) { //todo 实现代码 } } ``````

#### 测试用例样例

 `123456789101112131415161718192021222324` ``````import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Test; public class SumFractionsTest { private static void testing(String actual, String expected) { assertEquals(expected, actual); } @Test public void test1() { System.out.println("Fixed Tests sumFracts"); int[][] a = new int[][] { {1,2}, {2,9}, {3,18}, {4,24}, {6,48} }; String r = "[85, 72]"; testing(SumFractions.sumFracts(a), r); a = new int[][] { {1, 2}, {1, 3}, {1, 4} }; r = "[13, 12]"; testing(SumFractions.sumFracts(a), r); a = new int[][] { {1, 3}, {5, 3} }; r = "2"; testing(SumFractions.sumFracts(a), r); a = new int[][] {}; r = null; } } ``````

### 题目分析

1.分数之和，需要计算两个分数的分母的最小公倍数，分母相同后，分子进行相加。 2.求最小公倍数，需要求两个数的最大公约数，然后两个数的乘积除以最大公约数。 3.求最大公约数的方法很多，最容易理解的就是分解质因数，然后将相同的质因数相乘

### 代码示例

#### 初级实现

 `12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091` ``````import java.util.Arrays; public class SumFractions { public static String sumFracts(int[][] input) { String result = null; if (input.length == 0) { return result; } for (int[] e : input) { if (e.length != 2 || e == 0) { return result; } } // 计算分母最小公倍数 int minCommMultiple = input; for (int i = 1; i < input.length; i++) { minCommMultiple = minCommMultiple(minCommMultiple, input[i]); } // 计算分子之和 int num = 0; for (int i = 0; i < input.length; i++) { int elemnet = minCommMultiple / input[i]; num += input[i] * elemnet; } // 如果能够整除，需要整除 if (num % minCommMultiple == 0) { result = num / minCommMultiple + ""; return result; } // 坑 int maxCommDivisor = maxCommDivisor(num, minCommMultiple); if (maxCommDivisor > 1) { num /= maxCommDivisor; minCommMultiple /= maxCommDivisor; } result = "[" + num + ", " + minCommMultiple + "]"; return result; } /** * 计算两个数的最小公倍数 * * @param a * @param b * @return */ public static int minCommMultiple(int a, int b) { int c = a * b; int maxCommDivisor = maxCommDivisor(a, b); // 数学之美：最小公倍数 * 最大公约数 = 两个数的乘积 c = c / maxCommDivisor; // System.out.println("最小公倍数：" + a + "," + b + "=>" + c); return c; } /** * 计算两个数的最大公约数 * * @param a * @param b * @return */ public static int maxCommDivisor(int a, int b) { int mid1, mid2, mid3; mid1 = a; mid2 = b; mid3 = 0; // 数学之美：最大公约数 =》 【质因数分解法】【短除法】【*辗转相除法】【更相减损法】 while (true) { mid3 = mid1 % mid2; if (mid3 == 0) break; else { mid1 = mid2; mid2 = mid3; } } // System.out.println("最大公约数：" + a + "," + b + "=>" + mid2); return mid2; } } ``````

#### 中级实现

 `123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051` `````` import java.util.stream.Stream; public class SumFractions2 { public static String sumFracts(int[][] input) { String result = null; if (input.length == 0) return result; for (int[] e : input) { if (e.length != 2 || e == 0) return result; } // 计算分母最小公倍数 int minCommMultiple = Stream.of(input).mapToInt(a->a).reduce(1, (a, b)->a*b/maxCommDivisor(a, b)); int num = Stream.of(input).mapToInt(a->a*(minCommMultiple/a)).sum(); // 如果能够整除，需要整除 if (num % minCommMultiple == 0) { result = num / minCommMultiple + ""; return result; } int maxCommDivisor = maxCommDivisor(num, minCommMultiple); num /= maxCommDivisor; int den = minCommMultiple / maxCommDivisor; result = "[" + num + ", " + den + "]"; return result; } public static int maxCommDivisor(int a, int b) { int mid1, mid2, mid3; mid1 = a; mid2 = b; mid3 = 0; while (true) { mid3 = mid1 % mid2; if (mid3 == 0) break; else { mid1 = mid2; mid2 = mid3; } } return mid2; } } ``````

#### 高阶实现

1. 引入BigInteger.gcd方法计算最大公约数，
2. 过程中不再转换（好处是逻辑的简单，坏处是有可能乘积越界）。

 `123456789101112131415` ``````import java.math.BigInteger; import java.util.Arrays; public class SumFractions3 { public static String sumFracts(int[][] l) { if (l.length == 0) return null; final int D = Arrays.stream(l).mapToInt(ar -> ar).reduce(1, (a, b) -> a * b); final int N = Arrays.stream(l).mapToInt(ar -> ar * D / ar).sum(); int gcd = BigInteger.valueOf(D).gcd(BigInteger.valueOf(N)).intValue(); return (D == gcd) ? String.valueOf(N / D) : String.format("[%d, %d]", N / gcd, D / gcd); } } ``````

#### 完整验证用例

 `123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113` ``````SumFractions input：[ [1, 2], [2, 9], [3, 18], [4, 24], [6, 48], ] --> [85, 72] SumFractions input：[ [1, 2], [1, 3], [1, 4], ] --> [13, 12] SumFractions input：[ [1, 3], [5, 3], ] => 2 SumFractions input：[ [12, 3], [15, 3], ] => 9 SumFractions input：[ [2, 7], [1, 3], [1, 12], ] --> [59, 84] SumFractions input：[ [69, 130], [87, 1310], [3, 4], ] --> [9177, 6812] SumFractions input：[ [77, 130], [84, 131], [60, 80], ] --> [67559, 34060] SumFractions input：[ [6, 13], [187, 1310], [31, 41], ] --> [949861, 698230] SumFractions input：[ [8, 15], [7, 111], [4, 25], ] --> [2099, 2775] SumFractions input：[ ] => null SumFractions input：[ [1, 8], [1, 9], ] --> [17, 72] SumFractions input：[ [2, 8], [1, 9], ] --> [13, 36] ------------ SumFractions input：[ [91, 92], [91, 93], ] --> [16835, 8556] SumFractions input：[ [195, 196], [195, 197], ] --> [76635, 38612] SumFractions input：[ [125, 126], [125, 127], ] --> [31625, 16002] SumFractions input：[ [127, 128], [127, 129], ] --> [32639, 16512] SumFractions input：[ [167, 168], [167, 169], ] --> [56279, 28392] SumFractions input：[ [102, 103], [102, 104], ] --> [10557, 5356] SumFractions input：[ [49, 50], [49, 51], ] --> [4949, 2550] SumFractions input：[ [179, 180], [179, 181], ] --> [64619, 32580] SumFractions input：[ [98, 99], [98, 100], ] --> [9751, 4950] SumFractions input：[ [16, 17], [16, 18], ] --> [280, 153] SumFractions input：[ [74, 75], [74, 76], ] --> [5587, 2850] SumFractions input：[ [192, 193], [192, 194], ] --> [37152, 18721] SumFractions input：[ [181, 182], [181, 183], ] --> [66065, 33306] SumFractions input：[ [91, 92], [91, 93], ] --> [16835, 8556] SumFractions input：[ [17, 18], [17, 19], ] --> [629, 342] SumFractions input：[ [180, 181], [180, 182], ] --> [32670, 16471] SumFractions input：[ [175, 176], [175, 177], ] --> [61775, 31152] SumFractions input：[ [183, 184], [183, 185], ] --> [67527, 34040] SumFractions input：[ [81, 82], [81, 83], ] --> [13365, 6806] SumFractions input：[ [87, 88], [87, 89], ] --> [15399, 7832] SumFractions input：[ [26, 27], [26, 28], ] --> [715, 378] SumFractions input：[ [118, 119], [118, 120], ] --> [14101, 7140] SumFractions input：[ [80, 81], [80, 82], ] --> [6520, 3321] SumFractions input：[ [133, 134], [133, 135], ] --> [35777, 18090] SumFractions input：[ [116, 117], [116, 118], ] --> [13630, 6903] SumFractions input：[ [113, 114], [113, 115], ] --> [25877, 13110] SumFractions input：[ [148, 149], [148, 150], ] --> [22126, 11175] SumFractions input：[ [47, 48], [47, 49], ] --> [4559, 2352] SumFractions input：[ [42, 43], [42, 44], ] --> [1827, 946] SumFractions input：[ [11, 12], [11, 13], ] --> [275, 156] SumFractions input：[ [29, 30], [29, 31], ] --> [1769, 930] SumFractions input：[ [34, 35], [34, 36], ] --> [1207, 630] SumFractions input：[ [125, 126], [125, 127], ] --> [31625, 16002] SumFractions input：[ [44, 45], [44, 46], ] --> [2002, 1035] SumFractions input：[ [37, 38], [37, 39], ] --> [2849, 1482] SumFractions input：[ [8, 9], [8, 10], ] --> [76, 45] SumFractions input：[ [119, 120], [119, 121], ] --> [28679, 14520] SumFractions input：[ [183, 184], [183, 185], ] --> [67527, 34040] SumFractions input：[ [153, 154], [153, 155], ] --> [47277, 23870] SumFractions input：[ [41, 42], [41, 43], ] --> [3485, 1806] SumFractions input：[ [68, 69], [68, 70], ] --> [4726, 2415] SumFractions input：[ [151, 152], [151, 153], ] --> [46055, 23256] SumFractions input：[ [88, 89], [88, 90], ] --> [7876, 4005] SumFractions input：[ [199, 200], [199, 201], ] --> [79799, 40200] SumFractions input：[ [83, 84], [83, 85], ] --> [14027, 7140] SumFractions input：[ [166, 167], [166, 168], ] --> [27805, 14028] SumFractions input：[ [181, 182], [181, 183], ] --> [66065, 33306] SumFractions input：[ [59, 60], [59, 61], ] --> [7139, 3660] SumFractions input：[ [116, 117], [116, 118], ] --> [13630, 6903] SumFractions input：[ [46, 47], [46, 48], ] --> [2185, 1128] SumFractions input：[ [137, 138], [137, 139], ] --> [37949, 19182] SumFractions input：[ [127, 128], [127, 129], ] --> [32639, 16512] SumFractions input：[ [68, 69], [68, 70], ] --> [4726, 2415] SumFractions input：[ [20, 21], [20, 22], ] --> [430, 231] SumFractions input：[ [93, 94], [93, 95], ] --> [17577, 8930] SumFractions input：[ [34, 35], [34, 36], ] --> [1207, 630] SumFractions input：[ [55, 56], [55, 57], ] --> [6215, 3192] SumFractions input：[ [31, 32], [31, 33], ] --> [2015, 1056] SumFractions input：[ [11, 12], [11, 13], ] --> [275, 156] SumFractions input：[ [199, 200], [199, 201], ] --> [79799, 40200] SumFractions input：[ [149, 150], [149, 151], ] --> [44849, 22650] SumFractions input：[ [184, 185], [184, 186], ] --> [34132, 17205] SumFractions input：[ [136, 137], [136, 138], ] --> [18700, 9453] SumFractions input：[ [37, 38], [37, 39], ] --> [2849, 1482] SumFractions input：[ [191, 192], [191, 193], ] --> [73535, 37056] SumFractions input：[ [106, 107], [106, 108], ] --> [11395, 5778] SumFractions input：[ [147, 148], [147, 149], ] --> [43659, 22052] SumFractions input：[ [110, 111], [110, 112], ] --> [12265, 6216] SumFractions input：[ [8, 9], [8, 10], ] --> [76, 45] SumFractions input：[ [4, 5], [4, 6], ] --> [22, 15] SumFractions input：[ [193, 194], [193, 195], ] --> [75077, 37830] SumFractions input：[ [105, 106], [105, 107], ] --> [22365, 11342] SumFractions input：[ [26, 27], [26, 28], ] --> [715, 378] SumFractions input：[ [193, 194], [193, 195], ] --> [75077, 37830] SumFractions input：[ [119, 120], [119, 121], ] --> [28679, 14520] SumFractions input：[ [179, 180], [179, 181], ] --> [64619, 32580] SumFractions input：[ [30, 31], [30, 32], ] --> [945, 496] SumFractions input：[ [30, 31], [30, 32], ] --> [945, 496] SumFractions input：[ [128, 129], [128, 130], ] --> [16576, 8385] SumFractions input：[ [9, 10], [9, 11], ] --> [189, 110] SumFractions input：[ [126, 127], [126, 128], ] --> [16065, 8128] SumFractions input：[ [80, 81], [80, 82], ] --> [6520, 3321] SumFractions input：[ [112, 113], [112, 114], ] --> [12712, 6441] SumFractions input：[ [22, 23], [22, 24], ] --> [517, 276] SumFractions input：[ [65, 66], [65, 67], ] --> [8645, 4422] SumFractions input：[ [198, 199], [198, 200], ] --> [39501, 19900] SumFractions input：[ [163, 164], [163, 165], ] --> [53627, 27060] SumFractions input：[ [21, 22], [21, 23], ] --> [945, 506] SumFractions input：[ [67, 68], [67, 69], ] --> [9179, 4692] SumFractions input：[ [46, 47], [46, 48], ] --> [2185, 1128] SumFractions input：[ [35, 36], [35, 37], ] --> [2555, 1332] SumFractions input：[ [70, 71], [70, 72], ] --> [5005, 2556] SumFractions input：[ [178, 179], [178, 180], ] --> [31951, 16110] SumFractions input：[ [96, 97], [96, 98], ] --> [9360, 4753] SumFractions input：[ [3, 4], [3, 5], ] --> [27, 20] SumFractions input：[ [145, 146], [145, 147], ] --> [42485, 21462] SumFractions input：[ [170, 171], [170, 172], ] --> [29155, 14706] SumFractions input：[ [165, 166], [165, 167], ] --> [54945, 27722] SumFractions input：[ [2, 3], [2, 4], ] --> [7, 6] SumFractions input：[ [16, 17], [16, 18], ] --> [280, 153] ``````

#### 总结
{"ft_lang_label":"__label__zh","ft_lang_prob":0.95297134,"math_prob":0.99270016,"size":831,"snap":"2022-40-2023-06","text_gpt3_token_len":806,"char_repetition_ratio":0.045949213,"word_repetition_ratio":0.0,"special_character_ratio":0.27075812,"punctuation_ratio":0.1484375,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9854523,"pos_list":[0,1,2],"im_url_duplicate_count":[null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-10-04T01:31:38Z\",\"WARC-Record-ID\":\"<urn:uuid:81ac96f5-abc1-4dcf-879b-7db5010f5314>\",\"Content-Length\":\"117265\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:fb8ae625-cd19-413b-bc95-cdfac975cc31>\",\"WARC-Concurrent-To\":\"<urn:uuid:37435c32-1d10-4743-8d04-eaa85e9a9015>\",\"WARC-IP-Address\":\"185.199.108.153\",\"WARC-Target-URI\":\"https://www.javanorth.cn/2021/08/22/CodeBank-0001/\",\"WARC-Payload-Digest\":\"sha1:ZMASEJY2ZU4IEJ4FPQRN6PTES2HSLV45\",\"WARC-Block-Digest\":\"sha1:2RMTVUKTU45IRGL2LHEU44SI2WKORQVW\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-40/CC-MAIN-2022-40_segments_1664030337446.8_warc_CC-MAIN-20221003231906-20221004021906-00402.warc.gz\"}"}