全排列的那些事兒

大佬們的寫的很好:

全排列1
全排列2
全排列3 這第三個鏈接裏去重全排列那一塊兒的去重似乎不太對,可以考慮下面我的思考與實現
類似於這位大佬的實現:全排列4

next_permutation實現:

(從小到大按字典序輸出下一個排列)

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int data[4] = {5, 2, 1, 4};
    sort(data,data+4);
    do{
        for(int i=0; i<4; i++){
            cout<<data[i]<<" ";
        }
        cout<<endl;
    }while(next_permutation(data,data+4));

    return 0;
}

運行結果:
在這裏插入圖片描述

遞歸實現:

#include <iostream>

using namespace std;
#define Swap(a,b){int temp=a; a=b; b=temp;}  //交換

int data[] = {1,3,5,7};
int num = 0;

void Perm(int begin, int end)
{
    int i;
    if(begin == end){  //遞歸結束,產生一個全排列(一個葉節點)
        for(int j=0; j<3; j++){  //打印全排列
            cout<<data[j]<<" ";
        }
        cout<<data[3]<<endl;
        num++;  //統計全排列個數
    }else  //沒到葉節點就遞歸下去
        for(i = begin; i<=end; i++){
            Swap(data[begin],data[i]);  //八當前的第i個數與後面的所有數交換位置
            Perm(begin+1,end);
            Swap(data[begin],data[i]);  //恢復上一級,用於下一次交換
        }

}

int main()
{
    Perm(0, 3);
    cout<<"全排列的個數:"<<num<<endl;
    return 0;
}

運行結果:
在這裏插入圖片描述

去重全排列:

如果數列中有重複的,比如1,3,5,5,7,此時該如何計算全排列呢?只需要去重即可。

#include <iostream>

using namespace std;
#define Swap(a,b){int temp=a; a=b; b=temp;}  //交換

int data[] = {1,3,3,7};
int num = 0;

bool isEqual(int k,int m)   //去重函數
{
    for(int i=k; i<m; i++)   //判斷a[k]到a[m-1]是否有與a[m]相同的元素,若存在,返回false
    {
        if(data[i] == data[m])
            return false;
    }
    return true;
}
void Perm(int begin, int end)
{
    int i;
    if(begin == end)   //遞歸結束,產生一個全排列(一個葉節點)
    {

        for(int j=0; j<3; j++)   //打印全排列
        {
            cout<<data[j]<<" ";
        }
        cout<<data[3]<<endl;
        num++;  //統計全排列個數
    }
    else   //沒到葉節點就遞歸下去
        for(i = begin; i<=end; i++)
        {
            if(isEqual(begin,i))
            {
                Swap(data[begin],data[i]);  //八當前的第i個數與後面的所有數交換位置
                Perm(begin+1,end);
                Swap(data[begin],data[i]);  //恢復上一級,用於下一次交換
            }
        }

}

int main()
{
    Perm(0, 3);
    cout<<"全排列的個數:"<<num<<endl;
    return 0;
}

打印n個數中任意m個數的全排列:

只需要將begin == end的判斷改爲 begin == m
如下:在數組中任取3個數的全排列只需:、
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章