給出的方法是生成第壹個排列,然後每次調用後面的函數都給出下壹個排列,這樣效率很高,而且這個函數可以內聯。
這是經典的排列組合算法嗎?妳可以在網上找到很多。
大概就是那種有指向運動的算法。讓我給妳找壹個。
我找了幾個,這是我覺得比較清楚的,可以仔細參考壹下,不明白的話再去搜別的。。
全排列的算法和這個不太壹樣。它需要壹點改變。
至於語言,應該沒有太大問題。。基礎版真的很少見,現在也懶得寫了。。妳還是壹個人。
★生成排列的算法:
比如要生成5,4,3,2,1的完全排列,先求12345的最小排列,然後調用n!二級STL算法中的Next_permutation()可以輸出所有的全排列。所以這個算法的細節就是STL算法中next_permutation()的實現機制。詳細的實現代碼,可以參考侯傑的STL源代碼分析,這裏我只說壹下我的理解:
1 & gt;首先,從最末端開始尋找兩個相鄰的元素,這樣第壹個元素是*i,第二個元素是*ii,並且滿足* I
2 & gt然後從末尾向前檢查,找到第壹個大於*i的元素,使之成為*k,將I和K元素對調。
3 & gt然後反轉ii和ii之後的所有元素,這就是“下壹個”排列。
prev_permutation()算法的思路基本相同,只是他們尋找的拐點不同。在next_permutation()算法中,他們尋找峰值拐點,而在prev_permutation()算法中,他們尋找谷值拐點。此外,在第二步中,prev_permutation()查找小於*i的第壹個元素,而不是大於* i的第壹個元素..
具體例子,有時間再給,現在來不及了:)
★生成組合的算法:
如下圖截圖所示,有全組合和r組合兩種情況。
這裏有壹個核心代碼:
// -
//生成下壹個組合(Rosen第286頁的算法)
// -
public int[] getNext () {
if (numLeft.equals (total)) {
num left = num left . subtract(big integer。壹);
返回a;
}
int I = r-1;
while (a[i] == n - r + i) {
I-;
}
a[I]= a[I]+1;
for(int j = I+1;j & ltr;j++) {
a[j]= a[I]+j-I;
}
num left = num left . subtract(big integer。壹);
返回a;//這裏返回的數組A存儲下標的排列組合。
}
此時,也許大家會有壹個疑問,如果不要求字符或字符串的排列組合呢?我們做什麽呢其實很簡單。妳只需要取數組的下標進行排列組合,返回它們下標的排列組合,然後從原數組中讀取字符串值,就可以輸出所有的排列組合結果。