集合的全排列問題(遞歸實現)


設R={r1,r2,r3,.....rn}要進行全排列的n個元素,集合X中元素的全排列記為perm(X),則(ri)perm(X)表示在全排列perm(X)的每一個排列前加上前綴ri得到的排列。R的全排列定義可歸納定義如下:

當n=1時,perm(R) = (r),其中r為集合R中唯一元素

當n>1時,perm(R)由(r1)perm(R1)、(r2)perm(R2).........構成

因此可以設計全排列的遞歸算法;

//產生元素k—m的全排列,作為k-1個元素的后綴
void Perm(int list[], int k, int m){
    //構成一次全排列,輸出結果
    if( k == m ){
        for( int i = 0; i < m; i++ )
            cout<<list[i]<<" ";
        cout<<endl; 
    }
    else{
        //在數組list中,產生元素k—m的全排列
        for( int j = k; j <= m; j++){
            swap(list[k],list[j]);
            Perm(list,k+1,m);
            swap(list[k],list[j]);
        } 
    } 
} 

遞歸實現對排列1,2,3,4進行全排列:

#include<iostream>
#include<algorithm> //sort(),swap()函數頭文件 
using namespace std;
void Perm(int a[], int k, int m){
    if( k == m ){
        for(int i = 0; i <= m; i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    else{
        for(int j = k; j <= m; j++){
            swap(a[k],a[j]);
            Perm(a,k+1,m);
            swap(a[k],a[j]);
        }
    }    
}
int main(){
    int a[4] = {1,2,3,4}; //對數組中的1,2,3,4進行全排列 
    Perm(a,0,3);
    return 0;
}

用C++STL庫中的next_permutation(start,end),實現對集合的全排列。

next_permutation(start,end),和prev_permutation(start,end)。這兩個函數作用是一樣的,區別就在於前者求的是當前排列的下一個排列,后一個求的是當前排列的上一個排列。至於這里的“前一個”和“后一個”,我們可以把它理解為序列的字典序的前后,嚴格來講,就是對於當前序列pn,他的下一個序列pn+1滿足:不存在另外的序列pm,使pn<pm<pn+1.

對於next_permutation函數,其函數原型為:

     #include <algorithm>

     bool next_permutation(iterator start,iterator end)

當當前序列不存在下一個排列時,函數返回false,否則返回true

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int a[4] = {1,2,3,4};
    do
    {
        cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<endl;
    }while(next_permutation(a,a+4));
    return 0;
}

另外,需要強調的是,next_permutation()在使用前需要對欲排列數組按升序排序。prev_permutation(start,end)在使用前需要對欲排列數組按降序排序

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM