重溫c語言之,7天開整,就是隨便的寫寫,第八天

我是一个小笨蛋發表於2024-11-08

一:函式

  1、遞迴

  題目:求n的階乘(不考慮溢位)

  上程式碼

 1 #include<stdio.h>
 2 int factorial(int n) {
 3     if (n > 1) {
 4         return n * (factorial(n - 1));
 5     }
 6     else
 7     {
 8         return 1;
 9     }
10 }
11 #include<stdio.h>
12 int main()
13 {
14     int num = 0;
15     printf("請打出想要輸出的數的階乘:");
16     scanf("%d", &num);
17     int ret=factorial(num);
18     printf("%d\n", ret);
19     return 0;
20 }

  這裡就是:運用了階乘運算的思想,

  1!=1*1

  2!=2*1!

  3!=3*2!

  4!=4*3!

  ·······

  n!=n*(n-1)!

  所以這裡就是運用這個想法來將執行的步驟進行簡略,從而使程式碼變成2行

  斐波那契數列:

 1 //斐波那契數列:f(n)=f(n-1)+f(n-2);
 2 // 1,1,2,3,5,8,13,21,34,55
 3 //求第n個斐波那契數
 4 int sequence(int n) {
 5     int ret = 0;
 6     if (n > 2) {
 7         ret = sequence(n - 1) + sequence(n - 2);
 8     }
 9     else
10     {
11         ret = 1;
12     }
13     return ret;
14 }
15 #include<stdio.h>
16 int    main() {
17     int num = 0;
18     printf("請輸入一個數字:");
19     scanf("%d", &num);
20     printf("這個數字的斐波那契值是:%d\n", sequence(num));
21     return 0;
22 }

  這裡還有一個非常經典的遞迴題目:漢諾塔

  從左到右有A、B、C三根柱子,其中A柱子上面有從小疊到大的n個圓盤,現要求將A柱子上的圓盤移到C柱子上去,期間只有一個原則:一次只能移到一個盤子且大盤子不能在小盤子上面,求移動的步驟和移動的次數

  先上程式碼,然後解釋

 1 #include<stdio.h>
 2 //n代表的是盤子數量
 3 //a是起始位置
 4 //b是中間位置
 5 //c是最終位置
 6 int move_cout = 0;
 7 void move(char a, char c) {
 8     printf("%c-->%c ", a, c);
 9     move_cout++;
10 }
11 void Hanoi(int n,char a,char b,char c) {
12     
13     if (n==1)
14     {
15         move(a, c);
16     }
17     else
18     {
19         Hanoi(n-1, a, c, b);
20         move(a, c);
21         Hanoi(n - 1, b, a, c);
22     }
23 
24 }
25 int main()
26 {
27     int n = 0;
28     printf("請輸入A盤上有多少個盤子:");
29     scanf("%d", &n);
30     Hanoi(n,'A','B','C');
31     printf("\n%d\n", move_cout);
32     return 0;
33 }

  這裡先想,如果只有一個盤子,那會發生什麼:A-->C,將a上面的盤子直接移動到c上面

  再想,如果a上面有2個盤子呢,A-->B, A-->C ,B-->C,先將a最上面的盤子移動到c,再將a上面的盤子移動到c盤,最後將b盤上面的盤子移動到c盤

  再次想象,如果a上面有3個盤子呢,A-->C, A-->B, C-->B, A-->C, B-->A, B-->C, A-->C,現將a最上面的盤子移動到c,再將a裡面的第二個盤子移動到b,再講c裡面的盤子移動到b,之後就把a上面最後一個盤子移動到c,然後將b上面的盤子移動到a,之後再將b的盤子移動到c,最後將a的盤子移動到c,完成移動

  由此可得,盤子移動有兩種情況,1種:只有或者只剩下一個盤子的時候,只需將盤子移動到c即可;2種:盤子的數量大於1個的時候,那就需要這3根柱子相互配合,一起完成操作,最終才能將盤子移動到c柱子上面,這裡只不過遞迴了移動這個步驟

  2、迭代

  也是求階乘,題目與上述的是一樣的

  直接上程式碼:

 1 #include<stdio.h>
 2 int factorial(int n) {
 3     int ret = 1;
 4     for (int i = 1; i <= n; i++)
 5     {
 6         ret *= i;
 7     }
 8     return ret;
 9 }
10 #include<stdio.h>
11 int main()
12 {
13     int num = 0;
14     printf("請打出想要輸出的數的階乘:");
15     scanf("%d", &num);
16     int ret=factorial(num);
17     printf("%d\n", ret);
18     return 0;
19 }

  這裡用到了迭代(迴圈)

  斐波那契數列:

 1 #include<stdio.h>
 2 
 3 int sequence(int n) {
 4     int a = 1;
 5     int b = 1;
 6     int ret = 0;
 7     if (n>2)
 8     {
 9         for (int i = 0; i < n - 2; i++) {
10             ret = a + b;
11             a = b;
12             b = ret;
13         }
14         return ret;
15     }
16     else
17     {
18         ret = 1;
19     }
20     return ret;
21 }
22 int    main() {
23     int num = 0;
24     printf("請輸入一個數字:");
25     scanf("%d", &num);
26     printf("這個數字的斐波那契值是:%d\n", sequence(num));
27     return 0;
28 }

  交換位置,來計算數列值

總結:遞迴程式碼簡單,但是效率太低

   迭代程式碼複雜,但是效率高

相關文章