1. 問題描述
給定一個大於2的偶數,請用算法實現,將其分解為兩個質數的和。
提示:質數是指除了能被1和它自身整除以外,不能被其他任何數整除的整數。
2. 算法分析
從這個問題的描述來看,其實這個算法不是太難,主要是提示信息很明確,基本算是基於提示信息,就很容易將核心的代碼寫出來,然后套用這個核心的代碼,即可將待處理的數分為兩個數之和,只有當兩個數都是質數的時候,才符合問題答案的要求,即可返回結果。按部就班的將人類語言翻譯成機器代碼即可解決本問題
1). 判斷一個數是否為質數。
主要的邏輯就是將這個數n,循環的進行和【2,n/2】的每一個數進行求余數,只要有一個余數不為0,即得知n不是質數。(充分利用問題的提示信息,翻譯成機器語言)
2). 將待處理的偶數x,進行分解,分解為a,x-a兩部分(a >=2)
3). 在[a, x/2]之間循環調用步驟1)中的函數,判斷步驟2)中的a和x-a是否同時為質數
4). 只有步驟3)返回值為true的時候,退出循環,返回求出的兩個質數
注意,上面算法步驟中,之所以考慮到取半數進行處理,是因為待處理的數據和邏輯存在對稱效應,所以,為了提高處理性能,避免無效的計算開銷,采取取半執行。
3. 代碼實現
package even2prime; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; /** * @author shihuc * @date 2018年6月21日 上午10:35:15 * * 給定一個大於2的偶數,將其分解成兩個質數的和。所謂質數,就是指除了1和它自身之外,沒有能夠被整除的數。 * * 注意: 1即不是質數也不是合數,2是最小的質數。 */ public class Solution { /** * @author shihuc * @param args */ public static void main(String[] args) { Scanner scan = null; try { scan = new Scanner(new File("./src/even2prime/input.txt")); int count = scan.nextInt(); for(int i = 0; i < count; i++){ int even = scan.nextInt(); int prims[] = divEven2Prime(even); System.out.println("No." + i + ": even=" + even + ", prime1=" + prims[0] + ", prime2=" + prims[1]); } } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (scan != null){ scan.close(); } } } /** * 將目標數據分解為兩個質數的具體實現邏輯 * * @author shihuc * @param src * @return */ private static int[] divEven2Prime(int src){ int prime2[] = new int[2]; int middle = src / 2; for(int ele=2; ele <= middle; ele++){ if(isPrime(ele) && isPrime(src - ele)){ prime2[0] = ele; prime2[1] = src - ele; break; } } return prime2; } /** * 判斷當前數據是否是一個質數,核心思想是,將待判斷的數和[2,src/2]之間的每一個數進行求余,余數為0,則說明該src數不是質數。 * * @author shihuc * @param src * @return */ private static boolean isPrime(int src) { int src2 = 0; if(src == 2){ return true; }else if(src > 2){ src2 = src/2; } boolean flag = true; int next = 2; do{ //核心通過求余數是否為0,判斷能否被整除, 另外,為了提升性能,只需要求目標數的一半即可。 if(src % next == 0){ flag = false; break; } next++; }while(next <= src2); return flag; } }
4. 測試數據
7 4 18 100 200 300 4000 10000
5. 運行結果
No.0: even=4, prime1=2, prime2=2 No.1: even=18, prime1=5, prime2=13 No.2: even=100, prime1=3, prime2=97 No.3: even=200, prime1=3, prime2=197 No.4: even=300, prime1=7, prime2=293 No.5: even=4000, prime1=11, prime2=3989 No.6: even=10000, prime1=59, prime2=9941
總結:
1. 對於這種流程性的算法問題,重點抓住問題中的核心提示信息,將其用編程語言描述出來,即可完成問題的處理。
2. 算法問題,需要考慮性能,分析數據和問題邏輯,盡量避免不必要的CPU開銷,長期堅持節約或者資源用到刀刃上的習慣,軟件質量一般不會差。