全排列生成算法

全排列的生成算法, next_permutation_1 可以用于生成多重集的全排列,next_permutation_2不能用于多重集

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

bool next_permutation_1(vector<int>& vec){
    int n = vec.size()-1;
    for(;n>0;n--){
        if(vec[n]>vec[n-1]){
            break;
        }
    }
    if(n==0) return 0;
    int t = vec.size()-1;
    for(;t>0;t--){
        if(vec[t]>vec[n-1]) break;
    }
    swap(vec[t],vec[n-1]);
    for(t = vec.size()-1;t>n;t--,n++) swap(vec[n],vec[t]);
    return 1;
} 

bool next_permutation_2(vector<int>& vec, vector<int>& direct){
    int mx = -1, idx = -1, n = vec.size();
    for(int i=0;i<n;i++){
        if(i>0&&direct[i]&&vec[i-1]<vec[i]&&vec[i]>mx) idx = i,mx = vec[i];
        if(i<n-1&&!direct[i]&&vec[i]>vec[i+1]&&vec[i]>mx) idx = i ,mx = vec[i];
    }
    if(idx==-1)return 0;
    if(direct[idx]){
        swap(direct[idx-1],direct[idx]);
        swap(vec[idx-1],vec[idx]);
    }
    else
    {
        swap(direct[idx+1],direct[idx]);
        swap(vec[idx+1],vec[idx]);
    }
    for(int i = 0;i<vec.size();i++){
        if(vec[i]>mx) direct[i]^=1;
    }
    return 1;
}

int main(){
    int n;
    scanf("%d",&n);
    vector<int> vec,vec2,dir;
    for(int i=1;i<=n;i++) vec.push_back(i);
    for(int i=1;i<=n;i++) vec2.push_back(i),dir.push_back(1);
    printf("from next permutation 1
");
    do{
        for(int i=0;i<vec.size();i++){
            printf("%d ",vec[i]);
        }
        printf("
");
    }while(next_permutation_1(vec));
    printf("from next permutation 2
");
    do{
        for(int i=0;i<vec2.size();i++){
            printf("%d ",vec2[i]);
        }
        printf("
");
    }while(next_permutation_2(vec2,dir));
}
原文地址:https://www.cnblogs.com/zhjou/p/4758724.html