1 / 32

5.13 遞迴

5.13 遞迴. 遞迴函數 函數會呼叫他自己 只會解決最基本的情況 將問題分解成兩個區塊 知道怎麼做 不知道怎麼做 呼叫自己來解決已變小的問題 ( 遞迴步驟 ). 5.13 遞迴. Example: n 階乘 : 5! = 5 * 4 * 3 * 2 * 1 注意: 5! = 5 * 4! 4! = 4 * 3! ... 可以以遞迴的方式計算階乘 可以解決基本情況 (1! = 0! = 1) 則 2! = 2 * 1! = 2 * 1 = 2; 3! = 3 * 2! = 3 * 2 = 6;.

hu-stevens
Download Presentation

5.13 遞迴

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 5.13 遞迴 • 遞迴函數 • 函數會呼叫他自己 • 只會解決最基本的情況 • 將問題分解成兩個區塊 • 知道怎麼做 • 不知道怎麼做 • 呼叫自己來解決已變小的問題 (遞迴步驟)

  2. 5.13 遞迴 • Example: n 階乘: • 5! = 5 * 4 * 3 * 2 * 1 • 注意: • 5! = 5 * 4! • 4! = 4 * 3! ... • 可以以遞迴的方式計算階乘 • 可以解決基本情況 (1! = 0! = 1) 則 • 2! = 2 * 1! = 2 * 1 = 2; • 3! = 3 * 2! = 3 * 2 = 6;

  3. long 是指 long int的意思:即是用在會很大的整數變數 #include <stdio.h> long factorial( long ); int main(){ int i; for ( i = 1; i <= 10; i++ ) printf( "%2d! = %ld\n", i, factorial( i ) ); return 0; } long factorial( long number ){ if ( number <= 1 ) return 1; else return ( number * factorial( number - 1 ) ); } 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800

  4. 5.14 使用遞迴的實例: Fibonacci 級數 • Fibonacci 級數: 0 , 1 , 1 , 2 , 3 , 5 , 8 … • 每個數字都是前兩個數字的和 • fib(n) = fib(n-1) + fib(n-2):遞迴的公式 • long fib(long n) • { • if (n==0 || n==1) //基本情況 • return n; • else • return fib(n-1) + fib(n-2); • }

  5. 5.14 使用遞迴的實例: Fibonacci 級數 fib(3) return + fib(2) fib(1) return + fib(1) fib(0) return 1 return 1 return 0 fib(3)=1+0+1=2

  6. 完整的 Fibonacci 級數程式 #include <stdio.h> long fibonacci( long n ); int main() { long result; long number; printf( "Enter an integer: " ); scanf( "%ld", &number ); result = fibonacci( number ); printf( "Fibonacci( %ld ) = %ld\n", number, result ); return 0; } long fibonacci( long n ) { if ( n == 0 || n == 1 ) return n; else return fibonacci( n - 1 ) + fibonacci( n - 2 ); }

  7. Enter an integer: 2 Fibonacci(2) = 1 Enter an integer: 3 Fibonacci(3) = 2 Enter an integer: 4 Fibonacci(4) = 3 Enter an integer: 5 Fibonacci(5) = 5 Enter an integer: 6 Fibonacci(6) = 8 Enter an integer: 10 Fibonacci(10) = 55 Enter an integer: 20 Fibonacci(20) = 6765 Enter an integer: 30 Fibonacci(30) = 832040 Enter an integer: 35 Fibonacci(35) = 9227465

  8. 5.15 遞迴 vs. 迭代 • 重複性 • 迭代:明確地使用迴圈 • 遞迴:重複呼叫函式 • 何時終止? • 迭代:迴圈繼續條件失敗 • 遞迴:收斂到基本情況 • 兩者都可能出現無窮迴圈 • 均衡一下 • 選擇效能 (迭代所需的執行時間與記憶體比較小)與 軟體工程(遞迴使程式較容易被瞭解,有時也使問題比較簡化)

  9. 利用函式寫一個程式:要求輸入邊長s,隨即在螢幕左邊印出一s x s的正方形『*』,如:s = 4 **** **** **** ****

  10. #include <stdio.h> void square( int s ); int main() { int side; printf("輸入長度: " ); scanf( "%d", &side ); square( side ); return 0; } void square( int s ) { int i, j; for ( i = 1; i <= s; i++ ) { for ( j = 1; j <= s; j++ ) printf( "*" ); printf( "\n" ); } }

  11. 將前一個函式改為顯示字元可輸入 #include <stdio.h> void square( int side, char fillCharacter ); int main() { int s; char c; printf("輸入一個字元與長度: " ); scanf( "%c%d", &c, &s ); square( s, c ); return 0; }

  12. void square( int side, char fillCharacter ) { int loop; int loop2; for ( loop = 1; loop <= side; loop++ ) { for ( loop2 = 1; loop2 <= side; loop2++ ) printf( "%c", fillCharacter ); printf( "\n" ); } }

  13. Chapter 6陣列

  14. 章節大綱 6.1 簡介 6.2 陣列 6.3 定義陣列 6.4 使用陣列的例子 6.5 傳遞陣列給函式 6.6 陣列的排序 6.7 範例研究:使用陣列算平均數、中位數及眾數 6.8 搜尋陣列 6.9 多維陣列

  15. 6.2 陣列 陣列名稱 • 陣列 • 一群接連在一區的記憶空間位置 • 具有相同的名稱與型別 • 必須指定特定的名稱 • 陣列的名稱 • 以及位置編號 • 通式: 陣列名稱 [ 位置編號] • 第一個元素編號為 0 • 例如:C 陣列有n個元素如下: • c[ 0 ], c[ 1 ]...c[ n – 1 ] 位置編號

  16. 6.2 陣列 • 陣列的元素就像一般變數一樣 c[ 0 ] = 3; printf( "%d", c[ 0 ] ); • 另外,運算可以在位置編號中進行; 例如:若x = 3 c[ 5 - 2 ] == c[ 3 ] == c[ x ]

  17. 定義陣列 • 一開始要先定義宣告陣列(如一般變數) • 名稱 • 型別 • 元素個數 型別 陣列名稱[ 元素個數 ]; • 例如: int c[ 10 ]; float myArray[ 3284 ]; • 也可以將相同型別的陣列一同定義宣告 • 例如: int b[ 100 ], x[ 27 ];

  18. #include <stdio.h> int main() { int n[ 10 ], i; for ( i = 0; i <= 9; i++ ) n[ i ] = 0; printf("%s%13s\n ", “Element", “Value" ); for ( i = 0; i <= 9; i++ ) printf( "%7d%13d\n", i, n[ i ] ); return 0; } Element Value 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0

  19. 初始化串列 • 初始化串列 int n[ 5 ] = { 1, 2, 3, 4, 5 }; • 如果初始值個數少於陣列的元素個數則皆補 0, • 例如:int n[ 5 ] = { 0 } 則表示所有元素皆為 0 • 如果初始值過多會產生語法上的錯誤 • 如果在一個有初始化串列的定義上省略元素個數,  則元素個數將等於初始化串列上的元素個數, 例如: int n[ ] = { 1, 2, 3, 4, 5 }; 則此陣列的元素個數等於 5

  20. #include <stdio.h> int main() { int n[ 10 ] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 }; int i; printf( "%s%13s\n", "Element", "Value" ); for ( i = 0; i <= 9; i++ ) printf( "%7d%13d\n", i, n[ i ] ); return 0; } Element Value 0 32 1 27 2 64 3 18 4 95 5 14 6 90 7 70 8 60 9 37

  21. # define SIZE 10:前置處理器會在程式編譯之前將所有出現SIZE的地方代換為10 #include <stdio.h> #define SIZE 10 int main() { int s[ SIZE ], j; for ( j = 0; j <= SIZE - 1; j++ ) s[ j ] = 2 + 2 * j; printf( "%s%13s\n", "Element", "Value" ); for ( j = 0; j < SIZE; j++ ) printf( "%7d%13d\n", j, s[ j ] ); return 0; } Element Value 0 2 1 4 2 6 3 8 4 10 5 12 6 14 7 16 8 18 9 20

  22. Total of array element values is 383 #include <stdio.h> #define SIZE 12 int main() { int a[ SIZE ] = { 1, 3, 5, 4, 7, 2, 99,16, 45, 67, 89, 45 }; int i, total = 0; for ( i = 0; i <= SIZE - 1; i++ ) total += a[ i ]; printf( "Total of array element values is %d\n", total ); return 0; }

  23. 來看看這個程式多了什麼? #include <stdio.h> #define SIZE 10 int main() { int n[ SIZE ] = { 19, 3, 15, 7, 11, 9, 13, 5, 17, 1 }; int i, j; printf( "%s%13s%17s\n", "Element", "Value","Histogram" ); for ( i = 0; i <= SIZE - 1; i++ ) { printf( "%7d%13d ", i, n[ i ]) ; for ( j = 1; j <= n[ i ]; j++ ) printf( "%c", '*' ); printf( "\n" ); } return 0; }

  24. Element Value Histogram 0 19 ******************* 1 3 *** 2 15 *************** 3 7 ******* 4 11 *********** 5 9 ********* 6 13 ************* 7 5 ***** 8 17 ***************** 9 1 *

  25. #include <stdio.h> #include <stdlib.h> #include <time.h> int main(){ int face, roll, frequency1 = 0, frequency2 = 0; int frequency3 = 0, frequency4 = 0; int frequency5 = 0, frequency6 = 0; srand(time(NULL)); for ( roll = 1; roll <= 6000; roll++ ) { face = 1 + rand() % 6; switch ( face ) { case 1: ++frequency1; break; case 2: ++frequency2; break; 這是之前算擲6000次骰子的程式,還記得嗎? 

  26. case 3: ++frequency3; break; case 4: ++frequency4; break; case 5: ++frequency5; break; case 6: ++frequency6; break;} } printf( "%s%13s\n", "Face", "Frequency" ); printf( " 1%13d\n", frequency1 ); printf( " 2%13d\n", frequency2 ); printf( " 3%13d\n", frequency3 ); printf( " 4%13d\n", frequency4 ); printf( " 5%13d\n", frequency5 ); printf( " 6%13d\n", frequency6 ); return 0; }

  27. 算擲6000次骰子的程式,利用陣列可以改成這樣算擲6000次骰子的程式,利用陣列可以改成這樣 #include <stdio.h> #include <stdlib.h> #include <time.h> #define SIZE 7 int main() { int face, roll, frequency[ SIZE ] = { 0}; srand( time( NULL ) ); for ( roll = 1; roll <= 6000; roll++ ) { face = rand() % 6 + 1; ++frequency[ face]; } printf( "%s%17s\n", "Face", "Frequency" ); for ( face = 1; face <= SIZE - 1; face++ ) printf( "%4d%17d\n", face, frequency[ face ] ); return 0; } 當face=2時,程式 就將陣列[2]加1

  28. Face Frequency • 1 1029 • 2 951 • 3 987 • 4 1033 • 5 1010 • 6 990

  29. 字元陣列 • 單字 “first” 實際上可以視為一個字元陣列 • 字元陣列可以使用字串常數來指定初始值,例如: char string1[] = "first"; • 空字元 ‘\0’ 所有的字串都用它來終止 • 所以string1 實際上有六個元素 • 它等於: char string1[] = { 'f', 'i', 'r', 's', 't', '\0' }; • 可以直接存取字串中的個別字元,如: string1[ 3 ] 是字元 ‘s’ • 在scanf中,輸入陣列名稱不需要再加上『&』,如: scanf( "%s", string2 ); • scanf會讀取到出現第一個空格為止 • 讀入的字元數如果多過陣列元素數也會出現錯誤

  30. #include <stdio.h> int main() { char string1[ 20], string2[ ] = "string literal"; int i; printf(" Enter a string: "); scanf( "%s", string1 ); printf( "string1 is: %s\nstring2: is %s\n" "string1 with spaces between characters is:\n", string1, string2 ); for ( i = 0; string1[ i ]!= '\0'; i++ ) printf( "%c ", string1[ i ] ); printf( "\n" ); return 0; }

  31. Enter a string: Hello Kitty string1 is: Hello string2 is:string literal string1 with spaces between characters is: H e l l o

  32. 5/4 上機課 1. 請試著寫一個函式來判斷某數是否為質數 #include <stdio.h> int prime(int a); int main() { int x; printf("請輸入一整數:\n"); scanf("%d",&x); printf("\n"); return 0; } 主程式已在左邊請加入 prime函式在下面 If/else敘述式 印出(Yes or No)質數 2. 如果以做出上題,請印出1~10000所有的質數 prime函式

More Related