【編程思想】自頂向下 逐步求精
面向過程化編程思想:自頂向下 逐步求精
從程式執行的過程入手,將完整的過程細化成多個子過程,再將子過程細化,直到完成代碼。
我們來看一個程式需求:
驗證哥德巴哈猜想:任何一個大於 6 的偶數,都能分解成兩個質數的和。質數,指的 是除了 1 和本身之外,沒有別的因子的數。
要求:輸入一個整數,輸出這個數能被分解成哪兩個質數的和。
例如 : 輸入 14
14=3+11
14=7+7
這是一個比較複雜的程式。拿到這個程式的需求之後,首先應該先設計出程式的大體思路。
基本思路如下:
1、讀入一個整數 n
2、把這個整數拆成兩個數 a、b 的和
3、判斷 a 是否是質數
4、判斷 b 是否是質數
5、如果 3、4 兩個判斷都為真,則輸出 a 和 b
6、如果這個整數還能拆分,則回到第 2 步。否則程式退出
很顯然,2~6 步是一個迴圈,調整一下結構
如下: 讀取整數 n 迴圈(把整數 n 拆成兩個整數 a 和 b){
判斷 a 是否是質數
判斷 b 是否是質數
如果 a、b 都是質數,則輸出 a 和 b
}
在上面的基本思路中,我們可以看到,“判斷 a 是否是質數”和“判斷 b 是否是質數”這兩步操作基本一樣。因此,很顯然,這裡我們應該寫出一個函數,這個函數能夠判斷一個整數是否是質數。
import java.util.Scanner;public class TestGoldBach{public static void main(String args[]){//讀入整數Scanner sc = new Scanner(System.in);int n = sc.nextInt();迴圈{int a = 第一個整數int b = 第二個整數if (isPrime(a) && isPrime(b)){System.out.println(n + "=" + a + "+" + b);}}}//判斷一個整數是否是質數public static boolean isPrime(int a){}}
繼續細化。現在我們關注的重點是兩個:
1、如何把一個整數 n 拆成兩個整數 a 和 b;
2、如何判斷一個整數是質數。
首先,我們來看拆數的邏輯。如果能夠確定一個整數 a,則另外一個整數 b 也就確定 了,可以通過 b = n – a 這個式子計算出 b 的值。那麼如果給出一個整數,如何確定 a 的值呢。我們可以先看一個例子。假設 n 為 14,則所有拆數的拆法是:
1 + 13
2 + 12
3 + 11
4 + 10
5 + 9
6 + 8
7 + 7
在往下就是重複的拆法了。這樣,我們把第一個數當做 a,則 a 從 1 變化到 7,也就是 變化到 14/2。於是,我們拆數的迴圈就能夠分析出來了:
for(int i = 1; i<=n/2; i++){int a = i;int b = n-i;if (isPrime(a) && isPrime(b)){System.out.println(n + "=" + a + "+" + b);}}
至此,主函數全部完成。接下來,完成 isPrime 方法。對於如何判斷一個整數是否是質數,我們依然使用自頂向下,逐步求精的方式。由於質數,指的是除了 1 和本身之外,沒 有其他的因子,因此判斷一個整數 a 是否是質數,只要看 2~a-1 的範圍內有沒有 a 的因子就可以了。
因此,主要思路如下:
迴圈 i : 2~a-1{
如果 i是 a 的因子,則說明 a 不是質數 } 迴圈結束
則說明 2~a-1 都不是 a 的因子,因此 a 是質數
完整代碼如下:
package p5;import java.util.Scanner;public class TestGoldBach2{public static void main(String args[]){//讀入整數System.out.println("請輸入一個整數");Scanner sc = new Scanner(System.in);int n = sc.nextInt();for(int i = 1; i<=n/2; i++){int a = i;int b = n-i;if (isPrime(a) && isPrime(b)){System.out.println(n + "=" + a + "+" + b);}}}//判斷一個整數是否是質數public static boolean isPrime(int a){for(int i=2; i<= a-1; i++){if (a % i == 0) return false;}return true;}}
運行結果如下: