water_HUNG
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    ###### tags: `創造力資優課程` ###### tags: `computer` # C 語言課程 # 龍興國中 <font color="#3A33FF">創造力資優班 </font> ==C 語言課程== ![](https://i.imgur.com/ljOlYzv.png) ## 線上<font color="#3A33FF">程式語言</font>編譯平台: [onlinegdb](https://www.onlinegdb.com/) ## [學習 C 語言的好處--簡報](https://gamma.app/docs/C-d8ofw4mg5rwktb3) ## 1. C語言初體驗 : - 您可以編輯==程式碼==並在==onlinegdb==中執行並查看結果: :::success ``` #include <stdio.h> int main() { printf("Hello World!"); return 0; } ``` ::: ## 2. 什麼是C語言? - C 是丹尼斯·里奇於 1972 年在貝爾實驗室創建的通用程式 - 儘管它很古老,這是一種非常流行的程式語言。 - C 與 UNIX 密切相關,因為它是為編寫 UNIX 作業系統而開發的。 ## 3. 為什麼要學習 C? - 它是世界上最流行的程式語言之一[2023程式語言排名](https://www.johntool.com/programming-language-rank/) - 如果你懂 C,那麼學習其他流行的程式如 Java、Python、C++、C# 等也沒有問題,因為語法相似 - 與其他程式Java和Python)相比,C 語言執行速度非常快 - C 語言是通用的;它可以在不同硬體上的應用程式運作 - 學習 C 語言對於 ==APCS「大學程式設計先修檢測」== **觀念題**概念比較清楚 ## 4.C 和 C++ 之間的區別 - C++是 C 的擴展開發的版本,兩種語言的語法幾乎相同 - C 和 C++ 的主要區別在於 C++ 支持class和object,而 C 不支持 ## 5.程式範例說明 :::success ``` 1.#include <stdio.h> 2. 3.int main() { 4. printf("Hello World!"); 5. return 0; 6.} ``` ::: - 第 1 行: ==#include <stdio.h>== 是一個**函數庫**,可讓我們呼叫輸入和輸出的各種函數。 - 例如 ==printf()==(在第 4 行)。在 C 語言 **函數庫**中呼叫 ==printf()== 函數功能。 :::success 如果您不了解其 #include <stdio.h>工作原理,請不要擔心。只要把它想像成(幾乎)總是出現在你的 c 程式中的東西。 ::: - 第 2 行: ==空行==。C語言會忽略==空行==。但是我們使用==空行==會更容易讀懂程式內容。 - 第 3 行:另一個總是出現在 C 語言程式中的東西是 ==int main(){ }== 這稱為 ==函數==。大括號 =={ }== 內的任何程式都會被執行 - 第 4 行: ==printf()== 是將資料==輸出==到螢幕的函數。在我們的例子中,它將輸出==Hello World==。 :::warning 請注意:每句 C 語言程式碼都是以分號 ==;== 結尾 ::: - 第 5 行: ==return 0==結束 ==main( )== 函數。 - 第 6 行:不要忘記添加==右大括號== ==}== 以實際結束 main 函數。 ## 6.輸出 - printf()函數用於輸出==數值==或==文字==: ``` #include <stdio.h> int main() { printf("Hello World!"); printf("I am learning C."); return 0; } ``` :::danger 結果: Hello World!I am learning C. ::: - 換行符號 ==\n== ,它強制游標將其位置更改到螢幕中==下一行==的開頭。產生一個新的一行。 ``` #include <stdio.h> int main() { printf("Hello World!\n"); printf("I am learning C."); return 0; } ``` :::danger 結果: ``` Hello World! I am learning C. ``` ::: ## 7.註解 - 註解是用來解釋程式碼,並使其易於了解。它還可用於在測試替代程式碼時暫時停止執行。 - 註釋可以是單行或多行的 - 單行註解:以兩個 ==//== 開頭,編譯器不會執行這一行程式碼 ``` // 向世界問好 printf("Hello World!"); ``` ``` printf("Hello World!"); // 向世界問好 ``` - 多行註釋以開頭 ==/*== 和結尾 ==*/==。 - ==/*== 和之間的任何程式碼或文字 ==*/== 都將被編譯器忽略而不執行: ``` /* 下面的程式碼將會輸「Hello World!」字樣 到螢幕,真是太神奇了 */ printf("Hello World!"); ``` ## 8.變數 - **變數**可儲存被指定的**數據值**。 在 C語言中,不同類型的變數,有規定的==宣告==方式 例如: ==int== 儲存整數,例如 123 或 -123 ; ==float== 儲存浮點數,帶小數點的數字,例如 19.99 或 -19.99 ; ==char== 儲存單個字元,例如'a' or 'B'。字元值用單引號括起來 - 建立變數 a 以int方式並指定值為30 ``` int a = 30; ``` - 也可建立一個**變數**而不直接指定值,之後再指定數值: ``` int a; a = 30; ``` - 輸出 int **變數**的值,必須在函數內部使用格式說明符號 ==%d== 或 ==%i== 用雙引號括起來printf(): ``` int a = 30; printf("%d", a); ``` - 輸出 char **變數**的值,必須在函數內部使用格式說明符號 ==%c== 用雙引號括起來printf(): - 輸出 float **變數**的值,必須在函數內部使用格式說明符號 ==%f== 用雙引號括起來printf(): ``` // 建立變數 int myNum = 5; // 整數 float myFloatNum = 5.99; // 浮點數 char myLetter = 'D'; // 字元 // 輸出變數 printf("%d\n", myNum); printf("%f\n", myFloatNum); printf("%c\n", myLetter); ``` - **加總變數**:要將兩個變數加總,可以使用+ 運算符號 ``` int x = 5; int y = 6; int sum = x + y; printf("%d", sum); ``` - **宣告多個變數**:建立多個變數時,請使用==逗號==分隔 ``` int x = 5, y = 6, z = 50; printf("%d", x + y + z);//112.11.10-903 ``` ## 9.變數的命名規則 - 所有變數都必須指定唯一的識別碼。 - 識別碼可以是短代碼(如 x 和 y)或具描述性的代碼(age、sum、totalVolume)。 ==建議使用==描述性代碼讓程式碼易於理解和容易維護 例如: ``` int minutesPerHour = 60; // 很棒 int m = 60; // OK, 但不是很容易理解變數的內容 ``` - 命名==變數==的一般規則是: 名稱可以包含==字母、數字和下劃線_== 名稱必須以==字母或下劃線 (_) 開頭== 名稱區分==大小寫==(myVar 和 myvar 是不同的變數, 名稱不能包含==空格==或==特殊字符==,如 !、#、% 等。 ==保留字==(如int)不能用作名稱//111.9.28 ## 10.資料型態 - 宣告變數時要指定資料型態,並且在printf()中使用相關格式說明符號顯示: ``` // 宣告變數 int myNum = 5; // 整數 float myFloatNum = 5.99; // 浮點數 char myLetter = 'D'; // 字元 // 顯示列印變數 printf("%d\n", myNum); printf("%f\n", myFloatNum); printf("%c\n", myLetter); ``` ## 11.常數 - 將變數宣告為==常數==,意味只能讀取不可更改 ``` const int myNum = 15; // myNum 永遠是15 myNum = 10; // 錯誤: myNum 不可以再指定其他數值 ``` - 當變數的值永遠固定不能變更時,即可將該==變數==宣告為==常數== ``` const int minutesPerHour = 60;//一小時為60分鐘 const float PI = 3.14; //圓周率=3.14 ``` - 當宣告一個常數時,必須指定數值: :::success ``` const int minutesPerHour = 60; //正確 ``` ::: :::warning ``` const int minutesPerHour; minutesPerHour = 60; // 錯誤 ``` ::: ## 12.運算子 - 例子:我們使用 + 運算子將兩個==數值==相加: ``` int myNum = 100 + 50; ``` - 就像下面的例子一樣,一個==變數==可以和一個==數值==相加,或者一個==變數==相加另一個==變數== ``` int sum1 = 100 + 50; // 答案: 150 (100 + 50) int sum2 = sum1 + 250; // 答案: 400 (150 + 250) int sum3 = sum2 + sum2; // 答案: 800 (400 + 400) ``` ### 算數運算子 | 運算子 | 運 算 | Example | | -------- | -------| -------- | | + | 加法 | x + y | | - | 減法 | x - y | | * | 乘法 | x * y | | / | 除法 | x / y | | % | 餘數 | x % y | | ++| 增加1 | ++x | | - -| 減1| - -x | ### 賦值運算子 - 使用賦值運算子 = 分配 10 給名為x的變數: ``` int x = 10; ``` - 加法賦值運算子 += 將一個==數值==添加到==變數==中: ``` int x = 10; x += 5; //答案是 15 ``` | 運算子 | 例 子 | 等同 | | -------- | -------| -------- | | = | x =5 | x =5 | | += | x +=3 | x=x+3 | | -= | x -=3 | x=x-3 | | *= | x *=3 | x=x*3 | | /= | x /=3 | x=x/3 | | %=| x %=3 | x=x%3 | ### 比較運算子 比較運算子用於比較兩個數值。 注意:比較的結果可能回傳值為 true (1) 或 false ( 0)。 在以下示例中,我們使用==大於==運算子 > 來確定 5 是否大於 3: ``` int x = 5; int y = 3; printf("%d", x > y); // 回傳值為 1 (true) 因為 5 確實會大於 3 ``` | 運算子 | 意義 | 例子 | | -------- | -------- | -------- | | == |等於 |x == y | | != |不等於 |x != y | | > |大於 | x > y| | < |小於 |x < y| | >= |大於或等於 |x >= y| | <= |小於或等於 |x <= y| ### 邏輯運算子 邏輯運算子用於確定==變量==或==數值==之間的邏輯: | 運算子 | 名稱  | 意義  |舉例      | | -------- | -------- | -------- |-------- | |&& |且| 兩者都成立 |x < 5 && x < 10| ||| |或| 兩者其中之一成立 |x < 5 || x < 4 | |! |不是|回傳相反值|!(x < 5 && x < 10)|! |不是|回傳相反值|!(x < 5 && x < 10)| ### Sizeof 運算符 - sizeof運算子找到數據類型或變數的暫存大小 ``` int myInt; float myFloat; double myDouble; char myChar; printf("%lu\n", sizeof(myInt)); printf("%lu\n", sizeof(myFloat)); printf("%lu\n", sizeof(myDouble)); printf("%lu\n", sizeof(myChar)); ``` ## 13.if... else #### 從[比較運算子](https://hackmd.io/RudSoO7PRdOs9-rarcKyhg?both#%E6%AF%94%E8%BC%83%E9%81%8B%E7%AE%97%E5%AD%90)章節中可以知道 C 語言中常用的邏輯條件: - 小於: a < b - 小於或等於: a <= b - 大於: a > b - 大於或等於: a >= b - 等於 a == b - 不等於: a != b #### C語言有以下條件語句: - 使用 if 如果指定條件為==真==,執行指定的==區塊程式==。 - 使用 else 如果指定條件為==假==,執行指定的==區塊程式==。 - 使用 else if 如果第一個條件為假,測試新的==條件==。 - 使用 switch 指定執行多個不同的==區塊程式==。 :::success ### if 的語法 ``` if (指定條件) { // 如果指定條件為真,執行指定此區塊程式。 } ``` ![](https://i.imgur.com/OT0NgD7.png) #### if 的例子 - 在下面的例子中,我們測試 20 是否大於 18。如果條件為true,則印出"20 is greater than 18" - 注意 if 是小寫字母。大寫字母(If 或 IF)會產生錯誤。 ``` if (20 > 18) { printf("20 is greater than 18"); } ``` - 使用變數測試,結果成功 ``` int x = 20; int y = 18; if (x > y) { printf("x is greater than y"); } ``` ::: ### 練習題: ==1.如何判斷一個給定的數字是偶數還是奇數?== - 這是一個經典的C語言程式。 我們將在C語言中學習使用條件語句 if ,將一個整數除以2,如果整除(餘數為零),則該數是偶數,如果不能整除則該數是奇數。 ==2.輸入一個整數後即輸出該數的絶對值== - 不論該整數是正數或負數圴輸出正數 ==3.判斷三條線段是否可圍成一個三角形== - 3,4,5 可 - 6,6,12 不可 - 3,4,8 不可 :::warning ### if ....else 語法 ``` if (指定條件) { // 如果指定條件為真,執行指定此區塊程式。 } else { // 如果指定條件為假,執行指定此區塊程式。 } ``` ![](https://i.imgur.com/QrDtz6P.png) #### 例子 ``` int time = 13; if (time < 12) { printf("早安."); } else { printf("午安."); } // 輸出 "午安." ``` - 在上面的例子中,時間 13 大於 12,所以條件是false。因此,我們執行else區塊程式顯示出“午安”。如果時間小於 12,程式將顯示“早安”。 ::: ### 練習題: ==如何判斷一個給定的數字是偶數還是奇數?== - 這是一個經典的C語言程式。 我們將在C語言中學習使用條件語句if-else。將一個整數除以2,如果整除則是偶數,否則是奇數。 ==在三個數字中,找出最大的一個數字== - i : 3 - J : 4 - K : 5 :::danger ### if...else if...else 的語法 ![](https://i.imgur.com/zTzwZOU.png) ``` if (指定條件1) { // 如果指定條件1為真,執行指定此區塊程式。 } else if (指定條件2) { // 如果指定條件1為假,指定條件2為真,執行指定此區塊程式。 } else { //如果指定條件1為假,指定條件2為假,執行指定此區塊程式。 } ``` - 例子 ``` #include <stdio.h> int main() { int time = 22; if (time < 12) { printf("Good morning."); } else if (time < 20) { printf("Good day."); } else { printf("Good evening."); } // 輸出 "Good evening." } ``` - 在上面的例子中,時間 (22) 大於 12,所以第一個條件是false。語句中的下一個條件 else if也是false,因此我們繼續處理else 條件,因為條件1和條件2 都是false,所以螢幕顯示“Good evening.”。但是,如果時間是 ==14==,程式執行結果會是螢幕顯示“==Good day==”。 ::: ### 練習題 ==1.判斷 3 條線段是否可圍成三角形==: - 若可以圍成三角形則為下列何者1.正三角形,2.等腰三角形,3、直角三角形,4、普通三角形 :::info ### if....else 簡寫法與三元運算子 - 語法 ``` 變數 = (條件) ? True的結果 : False的結果; ``` - 例子 ``` int time = 20; if (time < 18) { printf("Good day."); } else { printf("Good evening."); } ``` - 本例的簡略的表達方式 ``` int time = 20; (time < 18) ? printf("Good day.") : printf("Good evening."); ``` ::: ## 14.switch :::success ![下午1.49 2024-11-20的影像](https://hackmd.io/_uploads/SyA5Ogjzkg.jpg) - 語法 ``` switch(變數名稱) { case 符合數字: 陳述句一; break; case 符合數字: 陳述句二; break; default: 陳述三; break; } ``` - 首先看看 switch 的括號,當中置放要取出==數值==的變數或運算式,取得數值之後,會與 case 設定的數字或字元比對,如果符合就執行以下的陳述句,直到遇到 break 後離開 switch 區塊,若沒有符合的數值或字元,會執行 default 後的陳述句,default 不需要時可以省略。 - 例子 ``` int day = 4; switch (day) { case 1: printf("Monday"); break; case 2: printf("Tuesday"); break; case 3: printf("Wednesday"); break; case 4: printf("Thursday"); break; case 5: printf("Friday"); break; case 6: printf("Saturday"); break; case 7: printf("Sunday"); break; } // Outputs "Thursday" (day 4) ``` - 例子2 ``` int rank = 4; switch (rank) { case 1: case 2: case 3: printf("電腦作業得95分"); break; case 4: case 5: printf("電腦作業得90分"); break; case 6: printf("電腦作業得80分"); break; } // Output "電腦作業得90分" (rank 4) ``` - 關鍵字 ==break== ,當程式執行到達關鍵字 ==break== 時,它會跳出 switch 區塊。停止在switch區塊內執行更多程式並忽略其他 ==case== 的測試。 ::: ### 練習題 #### ==1.兩光法師占卜術== - 兩光法師時常替人占卜,由於他算得又快有便宜,因此生意源源不絕,時常大排長龍,他想算 得更快一點,因此找了你這位電腦高手幫他用電腦來加快算命的速度。   他的占卜規則很簡單,規則是這樣的,輸入一個日期,然後依照下面的公式: M=月 D=日 S=(M*2+D)%3 得到 S 的值,再依照 S 的值從 0 到 2 分別給與 普通、吉、大吉 等三種不同的運勢 :::danger break 可以節省大量執行時間,因為它“忽略”了 switch 區塊中其餘程式的執行。 ::: :::warning - 關鍵字 ==default==,如果没有任何 ==case== 相符時,則執行一些預設程式。 - 例子 ``` int day = 4; switch (day) { case 6: printf("Today is Saturday"); break; case 7: printf("Today is Sunday"); break; default: printf("Looking forward to the Weekend"); } // Outputs "Looking forward to the Weekend" ``` ::: :::danger default 關鍵字必須是 switch 區塊中的最後一段陳述,並且不一定需要 break。 ::: ## 15.While 迴圈 :::info - 語法 ``` while (條件) { // 符合條件下會執行區塊內程式 } ``` - 例子 ``` int i = 0; while (i < 5) { printf("%d\n", i); i++; } ``` - 關於C語言中的while迴圈while1是什麼意思: - while(1)代表了迴圈永遠執行下去.除非遇到break;才跳出迴圈.原因是while的迴圈裡面是一個布林值,而1代表了true,所以是一個無限迴圈. ``` ``` ![](https://i.imgur.com/X78jQA7.png) ::: ### do....while 迴圈 ![](https://i.imgur.com/24iFA5k.png) :::info - 語法 ``` do { // 先執行區塊內程式一次,若條件符合則持續執行下去 } while (條件); ``` - 例子 ``` int i = 0; do { printf("%d\n", i); i++; } while (i < 5); ``` ::: ## 16. for 迴圈 :::success - 當明確知道重複執行一段程式的==次數==時,則使用 for 迴圈而不是 while 迴圈: - 語法 ``` for (陳述句1 ; 陳述句2 ; 陳述句 3) { // 執行區塊內的程式 } ``` #### 例子 1 ``` int i; for (i = 0; i < 5; i++) { printf("%d\n", i); } ``` ![](https://i.imgur.com/Uwx26gs.png) #### 例子 1 解說: - 陳述句 1 : 在迴圈開始之前建立一個變數,名為 ==i== ,起始值為 0 ( int i = 0)。 - 陳述句 2 : 定義了迴圈運行的條件(i 必須小於 5)。如果條件為==真==,迴圈將重複執行,如果條件為假,迴圈即結束。 - 陳述句 3 : 每次執行迴圈一次,==i== 的值都會增加 1 ( i++ )。 #### 例子 2 :本例僅會列印 0 到 10 之間的偶數 ``` for (i = 0; i <= 10; i = i + 2) { printf("%d\n", i); } ``` ![](https://i.imgur.com/SZmDphv.png) ::: ### 練習題 #### ==1.判斷一個整數,是質數還是合數,並找出所有的因數== - 質數只有1和該數本身共 2 個因數。 #### ==2.計算 1 加到 10 的總和== - 限用 for 迴圈完成。 #### ==3. 身份證字號真偽判斷== 我國的身分證字號有底下這樣的規則,因此對於任意輸入的身分證字號可以有一些基本的判斷原則,請您來判斷一個身分證字號是否是正常的號碼(不代表確有此號、此人)。 (1) 英文代號以下表轉換成數字 A=10 台北市 J=18 新竹縣 S=26 高雄縣 B=11 台中市 K=19 苗栗縣 T=27 屏東縣 C=12 基隆市 L=20 台中縣 U=28 花蓮縣 D=13 台南市 M=21 南投縣 V=29 台東縣 E=14 高雄市 N=22 彰化縣 W=32 金門縣 F=15 台北縣 O=35 新竹市 X=30 澎湖縣 G=16 宜蘭縣 P=23 雲林縣 Y=31 陽明山 H=17 桃園縣 Q=24 嘉義縣 Z=33 連江縣 I=34 嘉義市 R=25 台南縣 (2) 英文轉成的數字, 個位數乘9再加上十位數的數字 (3) 各數字從右到左依次乘1、2、3、4....8 (4) 求出(2),(3) 及最後一碼的和 (5) (4)除10 若整除,則為 real,否則為 fake 例: T112663836 ``` 2 + 7*9 + 1*8 + 1*7 + 2*6 + 6*5 + 6*4 + 3*3 + 8*2 + 3*1 + 6) = 180 ``` 除以 10 整除,因此為 real #### ==4.找零機器== 請設計一個找零機器的判斷程式,判斷使用者輸入的金額( money)當中,以最少的銅板數來找零錢。該機器所提供的銅板有 50 元、10 元、5 元及 1 元。當輸入的金額數介於 1 到 1000 之間,則依序顯示該找的各個銅板數(50 元、10 元、5 元及 1 元);當金額為 0 時,則結束判斷。 ## 17.Break 和 Continue :::info ### break : 前面章節中 break 可“跳出” switch 區塊程式。 - break 還可用於==跳出 while 、for 迴圈==。 - 下面例子在 i 等於 4 時==跳出迴圈==: ``` int i; for (i = 0; i < 10; i++) { if (i == 4) { break; } printf("%d\n", i); } ``` ::: ### 練習題 #### ==1.找出兩整數的最大公因數== - 變數設為num1,num2,餘數的變數設為remainder_ #### ==2.找出兩整數的最小公倍數== - 最小公倍數 = 兩數相乘 / 公因數 - [輾轉相除法參考資料](https://i.imgur.com/f8yA8VG.png) :::warning ### continue: 如果出現特定的條件,continue 會中斷一次迴圈結果,並繼續之後的迴圈。 - 下面例子在 i 等於 4 時,==跳過== 4 的值: ``` int i; for (i = 0; i < 10; i++) { if (i == 4) { continue; } printf("%d\n", i); } ``` ::: ## 18.陣列 :::success - ==陣列== : 可以在一個變數中儲存多個數值,而不用為每個數值宣告獨立的變數。 - 要建立陣列,要先定義==數據類型==(如int)並指定陣列名稱,後方加 []。 - 要在[]中加入數值,需在()內使用==逗號==分隔: - 例子:建立四個整數的陣列,陣列名稱為myNumbers。 ``` int myNumbers[] = {25, 50, 75, 100}; ``` ### 依據陣列索引號,存取陣列元素。 - 陣列索引號從 0 開始:[0] 是第一個元素。[1] 是第二個元素,依此類推。 - 下面例子是存取myNumbers陣列中的第一個元素 [0]的值: ``` int myNumbers[] = {25, 50, 75, 100}; printf("%d", myNumbers[0]); // 輸出答案為 25 ``` ### 更改陣列的元素 - 要依據索引號更改特定元素的值。 ``` int myNumbers[] = {25, 50, 75, 100}; myNumbers[0] = 33; printf("%d", myNumbers[0]); // 輸出結果為 33 取代原本的 25 ``` ### 搜尋陣列全部的元素 - 可以使用 for 迴圈搜尋陣列全部元素 。 以下例子輸出myNumbers 陣列中的所有元素: ``` int myNumbers[] = {25, 50, 75, 100}; int i; for (i = 0; i < 4; i++) { printf("%d\n", myNumbers[i]); } ``` ### 先設定陣列規模大小的陣列建立方法 - 另一種常用建立陣列的方法,先指定陣列的大小,然後再增添元素: - 例子: ``` / 宣告 4 個整數的陣列: int myNumbers[4]; // 增添元素在陣列中 myNumbers[0] = 25; myNumbers[1] = 50; myNumbers[2] = 75; myNumbers[3] = 100; ``` ### 陣列的練習 ``` #include <stdio.h> int main() { int myNumbers[3] ; for (int j = 0; j < 4; j++){ scanf("%d",&myNumbers[j]); } myNumbers[1] = 33; for (int i = 0; i < 4 ; i++){ printf("%d\n" , myNumbers[i]); } } ``` - 使用這種建立陣列的方法,必須先確定陣列的大小,才有足夠的記憶體空間讓程式去儲存。 - 建立陣列後,不能再更改它的規模大小。 ::: ## 練習題 ### [1.費波那契數列](https://docs.google.com/document/d/1tEBOikMGC-rKNly4GOOMTIhWm9PZd7bE0kcCRBzNpNQ/edit?usp=sharing) ## 19.字串 ## 20. scanf() 使用者輸入 :::warning - 你已經學過,用 printf() 輸出數值的方法。 - 要用戶輸入數值,可以使用 scanf() ![晚上9.50 2025-4-2的影像](https://hackmd.io/_uploads/HkQlWTqpye.jpg) - 例子 ``` // 建立一個資料類型為整數的變數,以便儲存使用者所輸入的數值 int myNum; // 詢問使用者要輸入一個數字 printf("Type a number: \n"); // 獲取且儲存使用者輸入的數字 scanf("%d", &myNum); // 輸出使用者輸入的數字 printf("Your number is: %d", myNum); ``` ``` scanf()函數有兩個參數:變數的格式說明符 %d 和引用運算符 &myNum,儲存變數的記憶體位址。 ``` ::: ## [21.字元陣列](https://www.lssh.tp.edu.tw/~hlf/class-1/lang-c/array-char.htm) ## [22.有限狀態機](https://medium.com/pm%E7%9A%84%E7%94%9F%E7%94%A2%E5%8A%9B%E5%B7%A5%E5%85%B7%E7%AE%B1/%E5%A6%82%E4%BD%95%E6%9C%89%E9%82%8F%E8%BC%AF%E7%9A%84%E9%87%90%E6%B8%85%E4%BA%8B%E7%89%A9%E7%9A%84%E7%8B%80%E6%85%8B-f9fb59b15054) ## [23.函式](https://mycollegenotebook.medium.com/%EF%BD%83%E8%AA%9E%E8%A8%80%E7%AD%86%E8%A8%98-%E5%87%BD%E5%BC%8F-functions-cea21d86560f) :::success ### 1. 函式介紹 - 在C語言中==函式==相當重要,可以減少許多繁雜的步驟,將程式變得容易閱讀理解。 - printf(),本質上也是一個函式。(利用 ==include <stdio.h>== 呼叫函式庫來使用) ### 2.函式的特色: - 指定一段程式碼,執行特定的工作。 - 可重複呼叫使用 - 讓程式變得容易閱讀理解。 - 在呼叫函式==條件不改變==的狀態下,可以==直接修改==函式的程式。 - 函式分為==系統定義==函式(如printf)和==使用者定義==函式兩種。 :::success - ==系統定義==函式(==標準函式庫==): 需==呼叫==標頭檔例如: - #include <stdio.h> - #include <stdlib.h> - #include <math.h> - 標準函式庫是C語言標準提供的函式庫,包含了大量的函式,可以幫助開發者簡化程式設計,加速開發速度。標準函式庫通常可以被編譯器直接調用,而不需要開發者自己編寫相關的代碼。 - C語言的標準函式庫可以分為幾個部分,每個部分包含了不同類型的函式: - 標準==輸出/輸入==函式庫:包括了與螢幕和鍵盤輸入輸出有關的函式,例如==printf、scanf==等。 - 字符串函式庫:包括了與字串處理有關的函式,例如strlen、strcpy、strcat等。 - 數學函式庫:包括了與數學運算有關的函式,例如sqrt、sin、cos等。 - 時間函式庫:包括了與時間有關的函式,例如time、ctime、gmtime等。 - 檔案操作函式庫:包括了與檔案操作有關的函式,例如fopen、fclose、fread等。 - 其他函式庫:還包括了與動態記憶體分配、環境變數、數據類型轉換等相關的函式。 ::: :::info - ==使用者定義==函式: ![](https://i.imgur.com/LGEIHXl.png) ![](https://i.imgur.com/QSDPlbQ.png) ![](https://i.imgur.com/6SJ4E3C.png) ![](https://i.imgur.com/lXQyTf3.png) - 回傳值:回傳一個int的型態回去主程式 在下方的程式中,當我們程式跑到 f(4)中,代表他呼叫了上方 ==int f(int x)== 函式,而因為這個函式有回傳值,所以在進行計算過後,我們有一個return x+3,把計算過後的答案傳回到主程式中 f(4) 就會等於回傳值 7,印出答案後程式結束執行。 :::success - 函式定義: 使用者定義函式 ==int f(int x){ return x +3; }== ``` int main() { printf("%d",f(4)); return 0; } ``` ::: :::success - 函式宣告: ::: - 在==主程式==上方,==宣告==函式原型(程式是由上而下讀取,告訴主程式說我設的函式的大概內容),==參數可省略==,主程式下方才放置使用者定義的函式 ``` #include <stdio.h> int f(int ); //有回傳值的函式宣告 int main() { printf("%d",f(4)); return 0; } //以下是函式定義 int f(int x){ return x +3; } ``` ### 3.回傳值型態 #### ==沒有回傳值==:==void== square(int len) - 在下方的程式中,當我們程式跑到square(length)中,代表他呼叫了下方void square函式,而因為這個函式沒有回傳值,所以在印出答案中後,就直接結束程式的執行了(可以想像有一個return 0 函式下方)。 ![上午9.50 2024-3-6的影像](https://hackmd.io/_uploads/HJOMhrr6p.jpg) #### ==有回傳值==:==int== square(int length) - 回傳一個 int 的型態給 主程式 ![上午9.52 2024-3-6的影像](https://hackmd.io/_uploads/Hy_d2rBaT.jpg) ### 4. 函式宣告 - ==例==:寫一個計算正方形的程式,並且使用函式呈現。 - 在主程式上方,==宣告函式==(跟主程式說我建立的函式樣式如何) - 再從主程式下方==定義函式== ``` 回傳值型態 函式名稱 (參數) ``` ![上午10.19 2024-3-6的影像](https://hackmd.io/_uploads/rJPTG8SaT.jpg) :::success 練習題:利用函式寫一個判斷[閏年的程式](https://onlinegdb.com/CJw5yMwx5e) - 輸入: 2011 - 輸出: 0 ``` #include <stdio.h>//閏年的規則,每四年閏一次,但是每一百年不閏,遇到四百年還是要閏 int main() { //int year = 112; int year; printf("請輸入任一年的數字"); scanf("%d",&year); if ( year % 400 == 0){//除以400的餘數為0,則為閏年 printf ("閏年"); } else if (year % 100 == 0){//再除以100的餘數為0,則為平年 printf ("平年"); } else if (year % 4 == 0){//再除以4的餘數為0,則為閏年 printf("閏年"); } else { printf("平年");//餘為平年 } } ::: :::success 練習寫一個計算面積的[公式1](https://onlinegdb.com/7lfKqR1FT),[公式2](https://onlinegdb.com/7ui63kcSd) - 公式: square = len *len ::: :::success - 無回傳值的函式 ::: :::info 在函式原型宣告時,第一個宣告的元素就是函式的傳回值的資料型別,任何的基本資料型別(如int, char, float, double...等)或自訂的資料型別都可以使用,但是如果函式不傳回任何值,則我們要把資料型別宣告為==void==,意思是不傳回值。 ::: ``` #include <stdio.h> void f(int ); //没有回傳值的函式宣告 int main() { f(4); return 0; } //以下是函式定義 void f(int x){ printf("%d",x+3); return ; } ``` :::success 練習寫一個==無回傳值==的計算面積[公式](https://onlinegdb.com/IExbb4gff) - 公式: square = len *len ::: ::: success - 兩個參數的函式 ::: :::info ``` int add(int x, int y) { // 函式定義為 add,参數列表為 x 和 y int result = x + y; // 將 x 和 y 相加,得到結果 return result; // 將結果回傳給函式呼叫者 } int main(){ int sum = add(3, 5); // 呼叫函數 add,並將結果指定給變數 sum } ``` ## [函式影片1](https://www.youtube.com/watch?v=QDcGPASnB6k) ## [函式解說1](https://hackmd.io/@twthe02/ry4gu9CJ3) ## [函式影片2](https://www.youtube.com/watch?v=5NN-G5BVEmo) ## [從費氏數列認識何謂遞迴-簡報](https://gamma.app/docs/-xcvfpbewsgzlkx5?mode=present#card-wz1qcib5e7i93m7) ::: - 根據費波那契數列的定義,要知道==第 n 項==,我們就需要知道==第 n-1 項==與==第 n-2 項==,於是在程式碼中我們可以看到,在 ==n 不等於 0 或 1 時==,f( ) 函式就會==呼叫函式自己==,只是這次是想要來計算第 n-1 項與第 n-2 項,所以就呼叫 f(n-1) 與 f(n-2)。 而要如何知道==第 n-1 項==是多少呢?我們這時就需要知道==第 n-2==與==第 n-3 項==,如此類推,最後直到我們想要知道的項為第 0 項與第 1 項時,因為這兩項已經被定義了,所以我們就能一一解答前面的所有項了。 還是有點抽象嗎?讓我們以計算 ==n=5== 時的費波那契數列為例,他在進行函式執行時的呼叫順序如下: ![下午5.24 2025-3-11的影像](https://hackmd.io/_uploads/HkWUGKTjJe.jpg) ![下午5.24 2025-3-11的影像 (1)](https://hackmd.io/_uploads/BJ2vGFps1g.jpg) - 費氏數列的==時間複雜度== 費氏數列的時間複雜度可直接使用觀察法。從上面的可以看出,每往下一層,每一項需要呼叫的次數就變成 2 倍,像 F(5) 要呼叫 F(4) + F(3) 而F(3) 要呼叫 F(2) + F(1) 等等。 而要找到數列的第 5 個數,我們需要的層數是剛好是 5 層,而推展到第 n 個數時,我們剛好需要 n 層。這個部分如果有點抽象的話,可以直接觀察上面的例子,圖中每一層的最左邊那項,是從 F(n) 一路遞減到 F(1),這樣剛剛好會是 n 層。 綜合結論:==時間複雜度約等於為 O(2ⁿ)== (2 的 n 次方)。 ## 練習題: - 利用函式遞迴法計算費氏數列問題 - 利用函式遞迴法計算最大公因數 ::: success ## [亂數](1https://blog.gtwang.org/programming/c-cpp-rand-random-number-generation-tutorial-examples/) - 使用 rand 函數產生亂數 - ==要先宣告相關函式== - #include <stdlib.h> /* 亂數相關函式 */ - #include <time.h> /* 時間相關函式 */ - C 語言中若要產生亂數,可以使用 stdlib.h 中的 rand 函式,而在呼叫 rand 函式之前,要先使用 srand 函式設定初始的亂數種子: ![上午9.04 2024-3-13的影像](https://hackmd.io/_uploads/ByksjdATp.jpg) - ==固定亂數種子==:上面的範例中,利用時間產生亂數種子,所以每次產生的亂數都不同,如果需要讓模擬的結果具有可重覆性以便除錯與驗證,這種狀況就必須將亂數種子==固定==不變,如果沒有固定亂數種子的話,每次跑出來的結果都不同,會讓除錯的難度提高。 ![上午9.30 2024-3-13的影像](https://hackmd.io/_uploads/H1RRbYC6T.jpg) - 產生==特定範圍整數亂數== ![上午9.36 2024-3-13的影像](https://hackmd.io/_uploads/HkTfmtCa6.jpg) ::: 練習題: :::success 寫一個程式,它可以處理任何筆數的成績,來處理全班分數。 第二個工作:重複輸入,直到輸入「-1」,才停止。 請輸出「輸入的分數筆數」。 輸入範例: 75 75 75 88 70 64 83 89 -1 輸出範例: 8 ::: :::warning 冒牌費氏數列 令: - f(1)=10,f(2)=15,f(3)=16 - f(n)={f(n-2)+f(n-3),當n>=4 請寫一個程式,輸入n,輸出f(n)值。 輸入範例: 5 輸出範例: 31 ::: - [zerojudge參考答案](1https://ffrankkk122.gitbooks.io/-zerojudge-code/content/a001.html) - [APCS檢定應試指南](https://hackmd.io/@howkii-studio/apcs_overview/https%3A%2F%2Fhackmd.io%2F%40howkii-studio%2Fapcs_exercise_programming) - [c語言實例100題](https://www.runoob.com/cprogramming/c-100-examples.html) - [幾A幾B猜數字](http://www.mathland.idv.tw/game/1A2B.htm) - [c 語言破解](1https://hackmd.io/@CHAWTeam/DiceC/https%3A%2F%2Fhackmd.io%2F%40CHAWTeam%2FDiceC-15-3) - [data-structure-c](https://github.com/ksw2000/Data-Structure-in-C) - [遞迴](https://hackmd.io/@sysprog/c-recursion) - [時間複雜度](https://gamma.app/docs/-602r2e5lfr671j2?mode=present#card-h3ceh3c5pycie5u) - [河內塔](https://gamma.app/docs/-mwnlaqx16gce2lm?mode=present#card-80h7wi5xtjascmz) - [河內塔遞迴概念](http://www.mathland.idv.tw/life/hanoirecursion.htm) - [河內塔遊戲](https://www.novelgames.com/zh-HK/tower/) - [河內塔演算法](https://ithelp.ithome.com.tw/articles/10245079) - [河內塔遞迴執行順序](https://ithelp.ithome.com.tw/articles/10281346) - [迭代版河內塔程式](http://squall.cs.ntou.edu.tw/cprog/practices/Iterative%20Hanoi.pdf) - [迭代與遞迴的差別-簡報](https://gamma.app/docs/-4nkgphbn7ze0u9v?mode=present#card-9l92ypzn5bvposl) - [遞迴 VS 迭代](https://hackmd.io/5T81GHb6RAihMSHQebVcZQ?both) - [費氏數列以迭代和遞迴實作簡報](https://gamma.app/docs/C--st7gd6widdmqwud?mode=present#card-56pslww4b01lfyo) - [如何將C語言程式轉換成執行檔.exe格式]![上午9.48 2025-4-25的影像](https://hackmd.io/_uploads/S1Dc9w_1gl.jpg) - [P問題和NP問題簡報](https://gamma.app/docs/PNP-NP-Complete--m4wdhtf4yjx0jmn?mode=present#card-x0xrgmbwb7twlzh) - [P問題和NP問題實例簡報](https://gamma.app/docs/PNP-7dph80gd8cj1leu?mode=present#card-milnn4qdgc8o2kf) - [P問題和NP問題](https://www.youtube.com/watch?v=YX40hbAHx3s) - [Kruskal's演算法簡報](https://gamma.app/docs/Kruskals--vq340e47isjxnhm?mode=present#card-hw2s5yfhnk7tzka) - [Kruskal's演算法與Prim演算法實例簡報](https://gamma.app/docs/Prim-Kruskal--3jx19li81crn55n?mode=present#card-hgvscrm08tsoajk) - [常見程式演算](https://openhome.cc/zh-tw/algorithm/) - [Coding Prep 程式教學](https://coding-prep.com/) - [APCS筆試題目分類](https://hackmd.io/@algoseacow/apps-written?fbclid=IwAR3PEteZkXjjWeiSZEkSR0Y1OdhRGuFZxIviMxwSk8HZ12V0z5ev5yy02so) - [APCS Code::Blocks 操作教學](https://hackmd.io/@smallshawn95/apcs_codeblocks?fbclid=IwAR1-2zUUf8KexWebx_x5fmUM0JydUzIC2yOXEDSGwUAVDufeMDBd0TExK20) - [程式自學平台](https://e-tutor.itsa.org.tw/e-Tutor/) - [如何在windows環境用gcc編譯成執行檔](https://shaochien.gitbooks.io/how-to-use-gcc-to-develop-c-cpp-on-windows/content/use-gcc-to-compile-program.html) - [新竹實驗中學C++講義](https://hackmd.io/@CLKO/B18yT_i5Z?type=view) - [zerojudge-高中生程式解題系統](https://zerojudge.tw/) ## [C語言程式轉換Java script ](https://b0933938087.blogspot.com/) ## [基礎C語言練習題](https://hackmd.io/@twthe02/S19lIMAxgl) - 📌 一、河內塔問題介紹: 河內塔問題是: 給定三根柱子與數個不同大小的盤子,要求依照一定規則(每次只移動一個盤子,且大盤子不能放到小盤子上)將所有盤子從起點柱子搬運到目標柱子上。 📌 二、問題特性與時間複雜度: 明確的遞迴解法: 河內塔問題有非常清晰的遞迴(Recursive)解法,可以在每一步遞迴中明確決定下一步該怎麼做。 演算法時間複雜度: 解決 N 個盤子的河內塔,所需步驟為 2ⁿ-1。 雖然看起來是指數成長,但仍屬於確定性演算法,且能夠清晰、直接地計算出每一步。 驗證解法: 不僅可以在多項式時間內驗證答案的正確性,還可以明確快速(多項式時間)地直接得到每一步的搬運順序。 📌 三、為何是 P 問題而非 NP 問題: 項目 河內塔問題特性 是否能有效求解? ✅ 可以快速且明確地找到解法 驗證答案正確性? ✅ 容易驗證(每一步都可以快速確認) 時間複雜度性質 ✅ 指數級但有明確且固定的步驟,屬於可有效計算 由於可有效地用一個確定性演算法解決,因此河內塔問題屬於 P 問題。 NP 問題的特性是可以快速驗證,但不一定能快速解決,典型如旅行推銷員問題(TSP)。 P 問題則是可快速找到有效的解法,典型如河內塔。 📌 四、為什麼河內塔是 P 但複雜度又是指數? 這裡需要釐清一點: 河內塔的最佳步驟數量是指數成長 𝑂(2ⁿ),但這個步驟數量是「已知且確定的」,能用一個非常簡單且明確的演算法(遞迴)精準求出答案,因此依計算複雜度理論的定義,它仍然被歸類在 P 問題的範疇內。 P 問題強調能用確定性的多項式時間演算法去求出解答步驟,而河內塔問題恰巧符合這種明確演算法的條件。 簡言之,河內塔問題雖步驟數指數級,但求解演算法簡明、確定,不具 NP 問題的「不確定性」特性。 - 「幾A幾B猜數字遊戲」,本質上可以視為一個搜尋問題: 你要從所有可能的數字組合中,透過每次猜測得到的提示(幾A幾B)逐步縮小可能的答案範圍,直到找到正確的數字。 在「複雜度理論」的角度,我們可以這樣判斷: P 問題(Polynomial time):可以在多項式時間內解出正確答案的問題。 NP 問題(Nondeterministic Polynomial time):如果給你一個「猜測答案」,你能在多項式時間內驗證這個答案對不對,但找到這個答案不一定容易。 幾A幾B猜數字遊戲是屬於哪一種? 答案是: 驗證一個猜測是否正確很快(只要比對兩組數字,看幾A幾B,用 O(n) 時間可以完成),所以這個問題一定屬於 NP。 至於「找到正確答案」這件事,有沒有辦法保證用多項式步驟內完成? 如果答案空間很大(例如猜的是 10 位數、數字可以重複),暴力猜測需要指數級的時間。 但如果題目的設定是小範圍(像猜 3 位數、不重複數字),人或電腦可以在合理步數內解出來。 所以一般來說,完整的「幾A幾B遊戲」屬於 NP 問題,但不一定是 NP-Complete。 如果限制輸入規模(例如最多 4 位數),那這種猜數字遊戲在實務上可以視為 P 問題; 但如果放寬規模(數字任意長),它就屬於 NP,甚至可能趨向 NP-hard。 簡單一句話總結: ➔ 「幾A幾B猜數字遊戲是 NP 問題,不一定是 P 問題。」 (可以快速驗證,但不保證可以快速找到答案,尤其當範圍變大時。) - 📌 一、終極密碼猜數字介紹: 通常設定一個介於某範圍內的數字,例如 1~100。 玩家每猜一次數字後,遊戲系統會告知「過大」或「過小」的提示。 玩家根據提示逐步縮小範圍,直到找到正確答案。 📌 二、為什麼是P問題: 有效演算法求解: 有明確且有效的演算法(如二分搜尋法),每次都能將可能的數字範圍縮小一半。 假設數字範圍為 1 到 n,最多只需 log₂n 次即可確定答案,屬於多項式時間內解決(甚至是對數級別,更快於一般多項式級)。 快速驗證: 不論是猜測還是驗證,都可以迅速完成。 📌 三、與NP問題的比較: 特性 終極密碼猜數字(P問題) NP問題(如旅行推銷員) 能否快速解決? ✅ 是 ❌ 不確定,目前未知快速解法 驗證答案是否快速? ✅ 是 ✅ 是 最佳解法 ✅ 有效解法:二分搜尋法 ❌ 一般只能暴力窮舉求解 終極密碼遊戲與NP問題(如背包問題或旅行推銷員問題)本質上不同。NP問題通常沒有已知的有效求解演算法;但終極密碼遊戲則有明確、高效率的求解方法(二分法)。 📌 四、終極密碼遊戲的時間複雜度: 使用最佳策略(二分搜尋)解題: 時間複雜度=O(log₂n ) 屬於非常有效率、快速解決的問題。 🌟 結論: 終極密碼猜數字遊戲屬於P問題,而非NP問題。 因為它具備快速、有效、確定性的求解方法(二分搜尋法),且其複雜度非常低。 - 旅行推銷員問題(Traveling Salesman Problem, TSP)是一個經典的NP問題。此問題的內容為:一位推銷員必須拜訪若干城市,每個城市僅能造訪一次,並且最終要回到出發城市。問題的目標是在所有可能的路徑中找到一條總路徑長度最短的路線。 TSP被歸為NP問題的主要原因,是因為我們尚未找到一個高效率的、多項式時間(polynomial-time)內求解的演算法。要找到TSP的最佳解,目前最直接的方法便是窮舉所有可能的路徑,計算每條路徑的長度,最後選出最短的路線。然而,對於n個城市,窮舉所有可能的路徑數量為(n-1)!,隨著城市數量增加,運算量呈現指數級成長,這種增長速度非常迅速,以致於在實務中難以有效求解。 儘管求解困難,但若給定一個可能的解答,要驗證這條路徑是否為有效路徑、以及是否滿足特定的總距離限制,卻是相對容易的,可以快速地在多項式時間內完成驗證。因此,TSP符合NP問題的重要特徵,也就是能夠快速驗證答案,但並不確定能否快速求解答案。 另外,TSP問題經典而重要的原因,在於它是「NP完全問題」(NP-complete) 中最具代表性的一種,NP完全問題是指一類問題,只要其中一個問題被證明能夠有效解決,則所有的NP問題都能有效解決。換言之,若有人能找到TSP的快速解法,則所有其他的NP問題也能一併被解決,這也正是電腦科學界至今對此問題投入大量研究心力的主要原因之一。 - 背包問題(Knapsack Problem)是一個著名的NP問題,在計算機科學、作業研究及組合優化領域中被廣泛研究。基本問題敘述是:有一個背包,其最大承重為W,同時有n個物品,每個物品有自己的重量和價值。目標是在不超過背包最大承重的前提下,選取物品組合,使得總價值最大化。 背包問題被認定為NP問題,主要是因為目前尚未找到一個能在多項式時間內有效解決所有情況的演算法。對於n個物品,每一個物品都有「放入」或「不放入」兩種選擇,因此總共有 2ⁿ 種可能的組合。要找到最佳解,最直接的方法是窮舉所有可能的物品組合,計算其總重量與總價值,再從中選出符合條件且價值最大的組合。由於組合數量隨著物品數量指數級成長,當n很大時,窮舉法變得極度耗時,因此無法在多項式時間內保證找到最佳解。 然而,若有人提供了一個特定的物品選擇方案,我們可以很容易地在多項式時間內驗證它是否合法(是否沒有超過承重且達到特定價值)。這正符合NP問題的定義:雖然不一定能快速找到解,但若有一個解,可以在多項式時間內驗證其正確性。 此外,背包問題有許多變體,如0/1背包問題、分數背包問題等。其中,「0/1背包問題」(每個物品只能選或不選)是典型的NP完全問題(NP-complete),也就是說,它不僅是NP問題,而且是最難的NP問題之一。這代表如果能找到一個多項式時間內解決0/1背包問題的方法,就能解決所有NP問題。 總結來說,背包問題因為符合「難以快速求解,但能快速驗證答案」的特徵,因此被歸類為NP問題,並且在理論計算與實務應用中都具有重要意義。

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully