推 j129008:雖然還沒看懂 感謝^_^ 05/04 05:19
※ 引述《j129008 (j129008)》之銘言:
: 問題(Question):
: 無法了解網路上的某篇程式
goto ......
: 程式碼(Code):(請善用置底文網頁, 記得排版)
break ......
: void make (int now,int a,int n,int m)
: {
: int b=a,c;
: if(now==m+1)
: {
: for(c=1; c<=m; c++)printf("%d ",way[c]);
: printf("\n");
: return;
: }
: else
: for(b=a; b<=n; b++)
: {
: way[now]=b;
: make(now+1,b+1,n,m);
: }
: }
: main()
: {
: while(scanf("%d %d",&n,&m)==2)
: make(1,1,n,m);
先看主程式呼叫 make 函數怎麼呼叫的,
: return 0;
: }
: 補充說明(Supplement):
: 已經想破腦袋了
: 甚至使用暴力法把程式怎麼跑的一一列出
: 結果就是看到函式進入堆疊以後不斷的recurtion就排出答案
: 最弄不懂的地方是make前面的兩個參數到底是怎麼做到組合的
: 希望有人可以幫我解答一下
主程式先取 n m 二數,表示 C n 取 m 的意思. 這二個數字本身有意義.
但是卻會呼叫 make(1,1,n,m) 開始. 前面二個參數看不出意義,但是在程式執行時
很重要,因為那些是執行時的中繼變數.
從定義 void make (int now,int a,int n,int m) 看到二個變數一個叫 now,
另一個叫 a, 很顯然 now 是指目前函式內容中最關注的一項訊息.
看一下 now 在 make 函式中出現的位置.
1. 在 else 之後第一個 now: 操作陣列中一個位置,使那個位置存入 b, 而 b
可能是 a 到 n 之間的數字.
2. else 之後第二個 now: now 是陣列中的位置,在下一個遞迴中, now 也變成
下一個 now (指 now+1).
3. 在 if 判斷中的 now: 如果 now 是 m+1, 而 m 的意思是取 m 的意思,
m+1 就是指 m 都取完了. 所以 now == m+1 是要結束遞迴. 結束的方法就是
把 way 陣列全都印出來. 而 way 陣列在前面 1. 2. 的 now 取值過程中,
有收集一些東西,那些東西就是答案.
所以看著 make 函式中的迴圈,
你可以想像迴圈從上往下把 way 的可能結果展開成一列一列.
把 way[now] = b 想像成從上往下在每一列同一個位置依序寫 a,b,c,..., 寫到 n.
(因為迴圈設定 a 到 n 嘛)
然後從迴圈中二行可以看到,前面把一列的前一個位置寫了一個 b, 之後遞迴呼叫
一定要給一個 b+1, 顯然這個 b, 即 make 函式的參數 a, 代表一個底數.
也就是說 make(now, a, n, m) 意思是在 a 到 n 範圍中取 m 個數字組合,
而目前正在取的數字位置是 now.
這樣胡言亂語一番之後,不知你是否懂了?
假如你看懂了,接下來會發現 make 函式一個怪怪的地方是,如果 n 比 m 小......
--
/yau
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 218.160.111.250
※ 編輯: yauhh 來自: 218.160.111.250 (05/03 23:44)