「MoreThanJava」Day 3:構建程序邏輯的方法

  • 「MoreThanJava」 宣揚的是 「學習,不止 CODE」,本系列 Java 基礎教程是本身在結合各方面的知識以後,對 Java 基礎的一個總回顧,旨在 「幫助新朋友快速高質量的學習」
  • 固然 不論新老朋友 我相信您均可以 從中獲益。若是以爲 「不錯」 的朋友,歡迎 「關注 + 留言 + 分享」,文末有完整的獲取連接,您的支持是我前進的最大的動力!

Part 1. 分支結構

  • 圖片來源:http://www.jituwang.com/vector/201512/569157.html

迄今爲止,咱們寫的 Java 代碼都是一條一條語句順序執行的,這種代碼結構一般稱之爲 順序結構html

然而僅有順序結構並不能解決全部的問題,好比咱們設計一個遊戲,遊戲第一關的通關條件是得到 1000 分,若是分數到達則進入下一關,若是未到達則 「Game Over」java

這裏就產生了兩個分支,並且這兩個分支只有一個會被執行。相似的場景還有不少,咱們將這種結構稱之爲 「分支結構」「選擇結構」git

「是否進入下一關」這樣的決策彷佛很小,可是在編程中,複雜的決策是由許多這種小的決策組成的。下面是實現是否進入下一關的程序演示:程序員

import java.util.Scanner;

public class Tester {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String answer;

        System.out.print("玩家是否達到 1000 分?(Y or N): ");
        answer = scan.nextLine();

        if ("Y".equals(answer)) {
            System.out.println("進入下一關");    // true branch
        } else {
            System.out.println("Game Over");   // false branch
        }
    }
}
複製代碼

程序首先提醒用戶用單一的字符 YN 來回答:github

System.out.print("玩家是否達到 1000 分?(Y or N): ");
複製代碼

而後使用 Scanner 類來獲取用戶的輸入:web

answer = scan.nextLine();
複製代碼

而後使用 if 關鍵字來判斷用戶輸入的字符是否等於 Y算法

if ("Y".equals(answer))
複製代碼

若是相等則進入 true branch,不然進入 false branch編程

縮進:數組

這裏 if 下方的縮進是爲了讓用戶更容易看到程序的邏輯,編譯器將忽略掉這些縮進。less

合理的縮進和程序佈局很重要,沒有適當的距離和縮進,看程序的邏輯有時會稍顯困難。您也指望儘量清晰地代表程序在作什麼不是嗎?

if 條件語句

在 Java 中,要構造分支結構可使用 ifelse 關鍵字。

if 語句的基本語法是:

if (條件) {
    // 條件知足時執行的語句
}
複製代碼

當條件知足時,則會執行 if 語句中的代碼塊兒,不然執行 if 語句塊後面的代碼。

例如:

public class Tester {

    public static void main(String[] args) {
        int n = 70;
        if (n >= 60) {
            System.out.println("及格了");
        }
        System.out.println("END");
    }
}
複製代碼

儘管當 if 語句塊只有一行語句時,能夠省略花括號 {}

if (n >= 60)
    System.out.println("及格了");
複製代碼

當這並非一個好主意。

假設某個時候,忽然想給 if 語句塊增長一條語句時:

public class Tester {

    public static void main(String[] args) {
        int n = 50;
        if (n >= 60)
            System.out.println("及格了");
            System.out.println("恭喜你"); // 注意這條語句不是if語句塊的一部分
        System.out.println("END");
    }
}
複製代碼

因爲使用縮進格式,很容易把兩行語句都當作 if 語句的執行塊,但實際上只有第一行語句是 if 的執行塊。

在使用 git 這些版本控制系統自動合併時更容易出問題,因此不推薦忽略花括號的寫法。(事實上,你使用 IDEA 的自動排版代碼的功能會幫你自動還原成有花括號的寫法,快捷鍵「ctrl + alt + l」)

else 語句

if 語句還能夠編寫一個 else { ... },當條件判斷爲 false 時,將執行 else 的語句塊:

public class Tester {

    public static void main(String[] args) {
        int n = 70;
        if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("掛科了");
        }
        System.out.println("END");
    }
}
複製代碼

修改上面代碼的 n 值,觀察 if 條件爲 true/ false 時,程序執行的語句塊。

注意,else 不是必須的。

還能夠用多個 if ... else if ... 串聯。例如:

public class Tester {

    public static void main(String[] args) {
        int n = 70;
        if (n >= 90) {
            System.out.println("優秀");
        } else if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("掛科了");
        }
        System.out.println("END");
    }
}
複製代碼

串聯的效果其實至關於:

if (n >= 90) {
    // n >= 90爲true:
    System.out.println("優秀");
else {
    // n >= 90爲false:
    if (n >= 60) {
        // n >= 60爲true:
        System.out.println("及格了");
    } else {
        // n >= 60爲false:
        System.out.println("掛科了");
    }
}
複製代碼

注意順序和臨界條件

在串聯使用多個 if 時,要特別注意判斷順序。觀察下面的代碼:

public class Tester {

    public static void main(String[] args) {
        int n = 100;
        if (n >= 60) {
            System.out.println("及格了");
        } else if (n >= 90) {
            System.out.println("優秀");
        } else {
            System.out.println("掛科了");
        }
    }
}
複製代碼

執行發現,n = 100 時,知足條件 n >= 90,但輸出的不是 "優秀",而是 "及格了",緣由是 if 語句從上到下執行時,先判斷 n >= 60 成功後,後續 else 再也不執行,所以,if (n >= 90) 沒有機會執行了。

正確的方式是按照判斷範圍從大到小依次判斷:

// 從大到小依次判斷:
if (n >= 90) {
    // ...
else if (n >= 60) {
    // ...
else {
    // ...
}
複製代碼

或者改寫成從小到大依次判斷:

// 從小到大依次判斷:
if (n < 60) {
    // ...
else if (n < 90) {
    // ...
else {
    // ...
}
複製代碼

使用 if 時,還要特別注意邊界條件。例如:

public class Tester {

    public static void main(String[] args) {
        int n = 90;
        if (n > 90) {
            System.out.println("優秀");
        } else if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("掛科了");
        }
    }
}
複製代碼

假設咱們指望 90 分或更高爲 「優秀」,上述代碼輸出的倒是 「及格」,緣由是 >>= 效果是不一樣的。

Part 2. 循環結構

  • 圖片引用自:https://www.zlovezl.cn/articles/two-tips-on-loop-writing/

順序結構的程序語句只能被執行一次。若是您想要一樣的操做執行屢次,就須要使用循環結構。

Java 中有三種主要的循環結構:

  • while 循環;
  • do...while 循環;
  • for 循環 (在 Java 5 中還引入了一種主要用於數組的加強型 for 循環)

while 循環

while 是最基本的循環,它的結構爲:

while ( 布爾表達式 ) {
  // 循環內容
}
複製代碼

只要布爾表達式爲 true,循環就會一直執行下去。

實例

public class Test {

    public static void main(String args[]) {
        int x = 10;
        while (x < 20) {
            System.out.println("value of x : " + x);
            x++;
        }
    }
}
複製代碼

以上實例編譯運行結果以下:

value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
複製代碼

do...while 循環

對於 while 語句而言,若是不知足條件,則不能進入循環。但有時候咱們須要即便不知足條件,也至少執行一次。

do…while 循環和 while 循環類似,不一樣的是,do…while 循環至少會執行一次。

do {
    // 代碼語句
while (布爾表達式);
複製代碼

注意:布爾表達式在循環體的後面,因此語句塊在檢測布爾表達式以前已經執行了。 若是布爾表達式的值爲 true,則語句塊一直執行,直到布爾表達式的值爲 false

實例

public class Test {

    public static void main(String args[]) {
        int x = 10;

        do {
            System.out.println("value of x : " + x);
            x++;
        } while (x < 20);
    }
}
複製代碼

以上實例編譯運行結果以下:

value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
複製代碼

for 循環

雖然全部循環結構均可以用 while 或者 do...while 表示,但 Java 提供了另外一種語句 —— for 循環,使一些循環結構變得更加簡單。

for 循環執行的次數是在執行前就肯定的。語法格式以下:

for(初始化; 布爾表達式; 更新) {
    // 代碼語句
}
複製代碼

關於 for 循環有如下幾點說明:

  • 最早執行初始化步驟。能夠聲明一種類型,但可初始化一個或多個循環控制變量,也能夠是空語句。
  • 而後,檢測布爾表達式的值。若是爲 true,循環體被執行。若是爲false,循環終止,開始執行循環體後面的語句。
  • 執行一次循環後,更新循環控制變量。
  • 再次檢測布爾表達式。循環執行上面的過程。

實例

public class Test {

    public static void main(String args[]) {

        for (int x = 10; x < 20; x = x + 1) {
            System.out.println("value of x : " + x);
        }
    }
}
複製代碼

以上實例編譯運行結果以下:

value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
複製代碼

您能夠再 IDEA 中快速輸入 fori 關鍵字來快速建立 for 循環的基本結構

控制循環

break 關鍵字

break 主要用在循環語句或者 switch 語句中,用來跳出整個語句塊。

break 跳出最裏層的循環,而且繼續執行該循環下面的語句。

實例

public class Test {

    public static void main(String args[]) {
        int[] numbers = {1020304050};

        for (int x : numbers) {
            // x 等於 30 時跳出循環
            if (x == 30) {
                break;
            }
            System.out.print(x);
            System.out.print("\n");
        }
    }
}
複製代碼

以上實例編譯運行結果以下:

10
20
複製代碼

continue 關鍵字

continue 適用於任何循環控制結構中。做用是讓程序馬上跳轉到下一次循環的迭代。

for 循環中,continue 語句使程序當即跳轉到更新語句。

while 或者 do…while 循環中,程序當即跳轉到布爾表達式的判斷語句。

實例

public class Tester {

    public static void main(String args[]) {
        int[] numbers = {1020304050};

        for (int x : numbers) {
            if (x == 30) {
                continue;
            }
            System.out.print(x);
            System.out.print("\n");
        }
    }
}
複製代碼

以上實例編譯運行結果以下:

10
20
40
50
複製代碼

Part 3. 構造程序邏輯

  • 圖片來源:http://www.mzh.ren/machine-learning-3.html

雖然迄今爲止咱們學習的內容只是 Java 的冰山一角,可是這些內容已經足夠咱們來構建程序中的邏輯。

對於編程語言的初學者來講,在學習了 Java 的核心語言元素 (變量、類型、運算符、表達式、分支結構、循環結構等) 以後,必須作的一件事情就是嘗試用所學知識去解決現實中的問題,換句話說就是鍛鍊本身把用人類天然語言描述的算法 (解決問題的方法和步驟) 翻譯成 Java 代碼的能力,而這件事情必須經過大量的練習才能達成。

咱們在這一 Part 爲你們整理了一些經典的案例和習題,但願經過這些例子,一方面幫助你們鞏固以前所學的 Java 知識,另外一方面幫助你們瞭解如何創建程序中的邏輯以及如何運用一些簡單的算法解決現實中的問題。

經典的例子

題目一:尋找水仙花數

說明:水仙花數也被稱爲超徹底數字不變數、自戀數、自冪數、阿姆斯特朗數,它是一個 3 位數,該數字每一個位上數字的立方之和正好等於它自己,例如:13 + 53+ 33=153

public class Tester {

    public static void main(String[] args) {
        findAllDaffodilNumberAndPrint();
    }

    /**
     * 查找全部的水仙花數並打印
     */

    public static void findAllDaffodilNumberAndPrint() {
        for (int num = 100; num < 1000; num++) {
            int low = num % 10;
            int mid = num / 10 % 10;
            int high = num / 100;
            // Math.pow(x, 3) 至關於求 x 的 3 次方
            if (num == Math.pow(low, 3) + Math.pow(mid, 3) + Math.pow(high, 3)) {
                System.out.println(num);
            }
        }
    }
}
複製代碼

題目二:百錢百雞問題

說明:百錢百雞是我國古代數學家張丘建在《算經》一書中提出的數學問題:雞翁一值錢五,雞母一值錢三,雞雛三值錢一。百錢買百雞,問雞翁、雞母、雞雛各幾何?翻譯成現代文是:公雞 5 元一隻,母雞 3 元一隻,小雞 1 元三隻,用 100 塊錢買一百隻雞,問公雞、母雞、小雞各有多少隻?

public class Tester {

    public static void main(String[] args) {
        getResultAndPrint();
    }

    /**
     * 獲取百錢百雞的結果並輸出
     */

    public static void getResultAndPrint() {
        for (int cockNum = 0; cockNum < 20; cockNum++) {
            for (int henNum = 0; henNum < 33; henNum++) {
                int chickNum = 100 - cockNum - henNum;
                if (5 * cockNum + 3 * henNum + chickNum / 3 == 100) {
                    System.out
                        .println("公雞:" + cockNum + "只, 母雞:" + henNum + "只, 小雞:" + chickNum + "只");
                }
            }
        }
    }
}
複製代碼

上面使用的方法叫作 窮舉法,也稱爲 暴力搜索法,這種方法經過一項一項的列舉備選解決方案中全部可能的候選項並檢查每一個候選項是否符合問題的描述,最終獲得問題的解。

這種方法看起來比較笨拙,但對於運算能力很是強大的計算機來講,一般都是一個可行的甚至是不錯的選擇,並且問題的解若是存在,這種方法必定可以找到它。

要點回顧

  1. 分支結構 ifelse 的使用和實例;
  2. 循環結構 whiledo...whilefor 循環的使用和實例;
  3. 控制循環的 breakcontinue 實例;
  4. 構建程序邏輯的練習;

練習

練習 1:百分之成績轉換成等級製成績

要求:

  1. 若是輸入成績在 90 分以上 (含 90 分) 輸出 A
  2. 80 ~ 90(不含 90) 輸出 B
  3. 70 ~ 80(不含 80) 輸出 C
  4. 60 ~ 70(不含 70) 輸出 D
  5. 60 分如下輸出 E

參考答案:

import java.util.Scanner;

public class Tester {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        int score = scan.nextInt();
        if (score >= 90) {
            System.out.println("A");
        } else if (score >= 80) {
            System.out.println("B");
        } else if (score >= 70) {
            System.out.println("C");
        } else if (score >= 60) {
            System.out.println("D");
        } else {
            System.out.println("E");
        }
    }
}
複製代碼

練習 2:輸入三條邊長,若是能構成三角形就計算周長和麪積

參考答案:

import java.util.Scanner;

public class Tester {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        double a = scan.nextDouble();
        double b = scan.nextDouble();
        double c = scan.nextDouble();

        if (a + b > c && a + c > b && b + c > a) {
            double perimeter = a + b + c;
            System.out.println("三角形周長爲:" + perimeter);

            double p = (a + b + c) / 2;
            double area = Math.sqrt(p * (p - a) * (p - b) * (p - c));
            System.out.println("三角形面積爲:" + area);
        } else {
            System.out.println("不能構成三角形!");
        }

    }
}
複製代碼

練習 3:打印以下所示的三角形圖案

*
**
***
****
*****
複製代碼
    *
   **
  ***
 ****
*****
複製代碼
    *
   ***
  *****
 *******
*********
複製代碼

參考答案:

import java.util.Scanner;

public class Tester {

    public static void main(String[] args) {
        System.out.println("請輸入行數:");

        Scanner scanner = new Scanner(System.in);
        int row = scanner.nextInt();

        for (int i = 0; i < row; i++) {
            for (int j = row - i - 1; j < row; j++) {
                System.out.print("*");
            }
            // 換行
            System.out.println();
        }

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < row; j++) {
                if (j < row - i - 1) {
                    System.out.print(" ");
                } else {
                    System.out.print("*");
                }
            }
            // 換行
            System.out.println();
        }

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < row - i - 1; j++) {
                System.out.print(" ");
            }
            for (int j = 0; j < 2 * i + 1; j++) {
                System.out.print("*");
            }
            // 換行
            System.out.println();
        }
    }
}
複製代碼

自取資料

優秀入門資料選取

  1. Introduction to Computer Science using Java - http://programmedlessons.org/Java9/index.html
  2. Java零基礎入門教程包含面向對象 - https://study.163.com/course/courseMain.htm?courseId=1003108028
  3. 網易雲課堂 - 頂尖中文大學計算機專業課程體系 - https://study.163.com/curricula/cs.htm
  4. TeachYourselfCS-CN (自學計算機科學) - https://github.com/keithnull/TeachYourselfCS-CN
  5. C語言中文網 Java 入門系列教程 - http://c.biancheng.net/java/10/
  6. 廖雪峯 Java 教程 - https://www.liaoxuefeng.com/wiki/1252599548343744
  7. 注重動手能力的 Java 教程 - https://how2j.cn/

推薦書籍

Java 核心技術·卷 I(原書第 11 版)

推薦理由: 這本書在知識體系完整充實的同時,又比《Thinking in Java》暴風式的知識洗禮來得輕鬆,新人入門書籍強烈推薦!

碼出高效:Java開發手冊

推薦理由: 阿里系出品。從最基礎的計算機基礎入手,到 Java 的方方面面,加上精美的配圖和通俗易懂的解釋,是很是適合新手閱讀的一本兒關於 Java 的技術書籍。

參考資料

  1. 《Java 核心技術 卷I》(第11版)
  2. Introduction to Computer Science using Java - http://programmedlessons.org/Java9/index.html#part02
  3. 菜鳥教程 - https://www.runoob.com/java/
  4. C語言中文網 Java 入門系列教程 - http://c.biancheng.net/java/10/
  5. Python 100 天重新手到大師 - https://github.com/jackfrued/Python-100-Days
  • 本文已收錄至個人 Github 程序員成長系列 【More Than Java】,學習,不止 Code,歡迎 star:github.com/wmyskxz/Mor…
  • 我的公衆號 :wmyskxz, 我的獨立域名博客:wmyskxz.com,堅持原創輸出,下方掃碼關注,2020,與您共同成長!

很是感謝各位人才能 看到這裏,若是以爲本篇文章寫得不錯,以爲 「我沒有三顆心臟」有點東西 的話,求點贊,求關注,求分享,求留言!

創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!

相關文章
相關標籤/搜索