1樓:匿名使用者
排列還比較好理解。可以想象我們手動進行排列,比如對於1,2,3這個序列,我們要輸出它的所有排列,那麼正常情況下我們怎麼做這個排列呢?
我們肯定是先在這個序列中選出乙個數,之後再在剩餘的序列中繼續選,直到最後乙個數(此時我們不用選了,因為只有乙個數)。
用組合來表示的話就是
但其實上面的式子等於
上式就是全排列。
那麼對於1,2,3這個序列,我們假定有乙個列表l存放我們排列的元素,我們可以
在1,2,3中選1,放到l
再在2,3中選2,放到l
之後只能選3,放到l
排列結束
注意,我們可以這麼考慮上面的過程:總是在剩餘的序列中選擇乙個整數。這樣,對於第一步而言,剩餘的序列其實就是整個序列。
現在來看**:
void perm(int k,int m)
這個表示我要對第k到第m-1個元素之間進行排列,而對於第0到第k-1個元素其實就是排列好的。
for(int i=k;i
回到我們上面對於1,2,3序列步驟的描述。
1中其實做的就是在剩餘序列(這裡是第k到第m-1個元素)中選出乙個元素,即第i個元素,並放到我們上面講的l中。由於這裡我們直接利用list來訪問這個元素,所以我們將第i個元素存放到list末尾,而注意到list中第0到第k-1個元素是排列好的,那麼就只能將第i個元素放到k的位置,這樣就代表插入到末尾了。由於我們將第i個元素挖掉了,但是我們前面將選出的第i個元素放到了第k的位置,那麼將原來第k個元素放到第i位置不就代表[k+1,m)個元素組成了剩餘序列嘛。
(每次迴圈代表一次排列,而1其實是順序選出這些元素。第一次迴圈我們選擇第k個元素,即剩餘序列中的第乙個,第二次,選擇第k+1個,即剩餘序列的第二個,依次類推。)
按照上面對perm的定義,2其實是對剩餘序列做排列,這裡剩餘序列是k+1到m-1個元素,因為k已經作為這次迴圈選擇的元素。
3是為了進行下一次排列做準備。我們在迴圈中在序列[k..m)中選擇了第i個元素,那麼下次我們就要在這原來的[k..
m)的序列中選擇第i+1個元素,為了將剩餘序列恢復,並且由於我們上一次迴圈將第i個元素放到了第k個的位置,所以在一次交換就變回來了。
if (k == m-1)
{for(int i=0;i
最後的輸出根據對排列的描述也就容易理解了,因為只剩下乙個元素,所以我們認為排列結束,所以就直接輸出了。
2樓:匿名使用者
// k 表示數列的前 k 個數 (即下標0到k-1) 已經被固定了
// m 表示總共有多少個元素void perm(int k, int m)cout << endl;
}// 否則我們從第 k 位開始往後的每一位都換到第 k 位來進行遞迴
else}}
求大神解答 乙個簡單的j**a問題
C語言程式遞迴問題跪求詳細解答
拿乙個等差數列來給你解釋,例如 1 2 3 4 5 100 如果我要計算前5項的和,那麼s5 a1 a2 a3 a4 a5 s5 5 s4 s4 4 s3 s3 3 s2 s2 2 s1 s1 a1 1 根據規律前n項和為 sn n s n 1 且s1 1,根據這兩個條件 我就可以求出任意sn的值,...
c語言問題求大神解答,C語言問題,求大神解答 20
a 用結構體定義以下學生資訊,結構體名 student 學號 姓名和成績 包括3門課程的成績,可用一個陣列表示 struct student c語言問題,求大神解答! 奔安 include include include typedef unsigned int uint typedef struc...
C語言問題,求解答,C語言問題,求大神解答
f函式中的a每次使用外面傳入的2,b是區域性變數,後每次都是1,c是靜態變數,函式每次執行會在上次值 1 所以最後執行三次,輸出為789 聽不清啊 程式的輸出是 789 c語言問題,求解答 執行abc a 1 首先進行巨集代換過程,是把 a 1去替代 定義的巨集函式 x x 中的x,即得到式子 a ...