实现词典排序以找到唯一排列

时间:2013-03-12 05:47:40

标签: c++ permutation

我正在尝试实现一种算法,以按照here描述的字典顺序生成唯一的排列。以下是我的实施。

void My_Permute(string word) {
    sort(word.begin(),word.end());
    int size = word.size(); 
    while (true) {
        cout << word << endl;
        int i = size - 2;  
        for (; i >= 0; --i) { 
            if (word[i] < word[i+1]) break; 
        } 
        if (i <= -1) break; 
        swap(word[i],word[i+1]);
        cout << word << endl;
        reverse(word.begin()+i+1,word.end());
    } 
} 

我确信算法是正确的,所以我的实现有什么问题?我的功能是错过了一些排列。以下显示我的输出与输入abcd上的std :: next_permutation进行比较。

My_Permute             std::next_permutation
abcd                   abcd
abdc                   abdc
abdc                   acbd
adbc                   adbc
adcb                   adcb
dacb                   bacd
dbca                   bcad
dcba                   bcda
dcab                   bdac
dcba                   bdca
dcba                   cabd
                       cadb
                       cbad
                       ...

1 个答案:

答案 0 :(得分:2)

你错过了链接算法的第2步

void Permute(string word) {
    sort(word.begin(), word.end());
    int size = word.size();
    while (true) {
        cout << word << endl;
        // Find the largest index k such that a[k] < a[k + 1].
        // If no such index exists, the permutation is the last permutation.
        int i = size - 2;
        for (; i >= 0; --i) {
            if (word[i] < word[i+1])
                break;
        }
        if (i < 0)
            break;
        // Find the largest index l such that a[k] < a[l].
        // Since k + 1 is such an index, l is well defined and satisfies k < l.
        int j = size - 1;
        for (; ; --j) {
            if (word[i] < word[j])
                break;
        }
        // Swap a[k] with a[l].
        swap(word[i], word[j]);
        // Reverse the sequence from a[k + 1] up to and including the
        // final element a[n].
        reverse(word.begin() + i + 1, word.end());
    }
}

输出是:

abcd
abdc
acbd
acdb
adbc
adcb
bacd
badc
bcad
bcda
bdac
bdca
cabd
cadb
cbad
cbda
cdab
cdba
dabc
dacb
dbac
dbca
dcab
dcba

24(即4!)行,如预期的那样

顺便说一句,你应尽可能avoid "using namespace std"