全排列
首先,給出算法的思路
設R={r1,r2,...,rn}是要進行排列的n個元素,Ri=R-{ri}。
集合X中元素的全排列記為permutation(X),(ri)permutation(X)表示在全排列permutation(X)的每一個排列前加上前綴ri得到的排列。
R的全排列可歸納定義如下:
當n=1時,permutation(R)={r},r是集合R中唯一的元素;
當n>1時,permutation(R)由(r1)permutation(R1),(r2)permutation(R2),……,(rn)permutation(Rn)構成。
此算法要求待排列的數據是互異的,因為該算法不能檢測同種排列是否已經輸出,如:
1, 1, 2
那么,全排列期望輸出是:
1, 1, 2
1, 2, 1
2, 1, 1
但是該算法的輸出:
1, 1, 2
1, 2, 1
2, 1, 1
1, 1, 2
1, 2, 1
2, 1, 1
這是該算法的缺點,也限制了它的適用范圍。
程序描述如下:
#include? < algorithm > ?
using ? namespace ?std;?
// ?遞歸產生R[k:n]的所有的排列,元素是互異的
template? < class ?Type >
void ?permutation(Type? * R, int ?k, int ?n)
{
???? if (k == n)
????{
???????? for ( int ?i = 0 ;i < n; ++ i)
????????????cout? << ?R[i]? << ? " \t " ;
????????cout? << ?endl;
????}
???? else
???????? for ( int ?i = k;i < n; ++ i)
????????{
????????????swap(R[k],R[i]);
????????????permutation(R,k + 1 ,n);
????????????swap(R[k],R[i]);
????????}
}
還有一種很簡單的方法,使用GP中的方法
該算法是STL中的范型算法,當然效果是很好的,不會出現上面的算法的情況。
程序描述如下:
#include? < iostream >
#include? < vector >
#include? < algorithm > ?
using ? namespace ?std;?
// ?產生R[k:n]的所有的排列
template? < class ?Type > ?
void ?pernutation(Type? * R, int ?k, int ?n)
{
?vector < Type > ?myVec;
? int ?i,size? = ?n? - ?k;
? for (i? = ?k;i? < ?n;i ++ )
??myVec.push_back(R[i]);
? // ?使用next_permutation()函數必須是有序的數據
?sort(myVec.begin(),myVec.end());
??
? do
?{
?? for (i? = ? 0 ;i? < ?size;i ++ )
???cout? << ?myVec[i]? << ? " \t " ;
??cout? << ?endl;
?}
? while (next_permutation(myVec.begin(),myVec.end()));
}
注:這里的待全排的數據是存在數組或者向量中的。
posted on 2006-12-25 10:17 Dain 閱讀(1163) 評論(2) 編輯 收藏 引用 所屬分類: 算法