1. 程式人生 > >LexicographicPermute(求字典序的下一個字典序)

LexicographicPermute(求字典序的下一個字典序)

虛擬碼

演算法 LexicographicPermute(n)

//以字典序產生排列

//輸入:一個正整數n

//輸出:在字典序下{1,……,n}所有排列的列表

初始化第一個排列為12……n

While 最後一個排列有兩個連續升序的元素 do

找到使得ai<ai+1的最大的i     //ai+1>ai+2>ai+3>……>an

找到使得ai<aj的最大索引j    //j>=i+1,因為ai<ai+1

交換ai和aj   //ai+1ai+2……an任保持降序

將ai+1到an的元素反序

將這個新排列新增到列表中

//14世紀印度時的某個演算法,感嘆啊,那個時候的人就這麼聰明瞭
//此方法可以用來求字典序的下一個序列
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void LexicographicPermute(int *a,int n)
{
    //開始時陣列a[0,1,2,3,……,n-1]的序列時為1,2,3,4,5……n
    int k=n-2,j;
    for(int i=0; i<n; i++)
        cout<<a[i]<<" ";
    cout<<endl;
    while(1)
    {
        for(j=n-1; j>k; j--)
        {
            if(a[j]>a[k])
            {
                swap(a[j],a[k]);
                break;
            }
        }
        for(int i=k+1; i<n-i+k; i++)
            swap(a[i],a[n-i+k]);
        for(k=n-1; k>0; k--)
            if(a[k]>a[k-1])
                break;
        for(int i=0; i<n; i++)
            cout<<a[i]<<" ";
        cout<<endl;
        if(k--==0) break;
    }
}
int main()
{
    int a[1000],n;
    cin>>n;
    for(int i=0; i<n; i++)
        a[i]=i+1;
    LexicographicPermute(a,n);
    return 0;
}