看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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)
j129008:雖然還沒看懂 感謝^_^ 05/04 05:19