簡單的字母全排列問題—遞歸法和STL法


問題描述:求全由小寫字母組成的不超過200個字符序列的全排列
如輸入序列bbjd,排列結果為:
bbdj
bbjd
bdbj
bdjb
bjbd
bjdb
dbbj
dbjb
djbb
jbbd
jbdb
jdbb
 
方法一:遞歸法
 
代碼如下:
 
#include <stdio.h>

int t[200]; char s[200]; int n = 0; void permutation(int i) { int k; // a~z的ASCII碼在97到122之間
    for(k = 97; k < 123; k++) { if(t[k]) { t[s[i] = k]--; permutation(i + 1); t[k]++; } } // 只有n個字母全部排好了才輸出
    n - i || puts(s); } int main() { int i; puts("Please Input letter sequence: "); gets(s); // t[]記錄每個字母的出現頻率 // n為待排序列的長度
    for(i = 0; s[i] != '\0'; i++) { t[s[i]]++; n++; } puts("Permutation result: "); permutation(0); return 0; }

運行結果如下:

 

方法二:STL法

C++的STL有一個函數可以方便地生成全排列,這就是next_permutation

在C++ Reference中查看了一下next_permutation的函數聲明:

#include <algorithm>
bool next_permutation( iterator start, iterator end );

The next_permutation() function attempts to transform the given range of elements [start,end) into the next lexicographically greater permutation of elements. If it succeeds, it returns true, otherwise, it returns false.

 

從說明中可以看到 next_permutation 的返回值是布爾類型。按照提示寫了一個標准C++程序:

其中用到了 sort 函數,如果不先排序,則完成不了全排列。

 

#include <iostream> #include <string> #include <algorithm>

using namespace std; int main() { string str; cout << "Please Input letter sequence: \n"; cin >> str; // 必須先排序
 sort(str.begin(), str.end()); cout << str << endl; cout << "Permutation result: \n"; while(next_permutation(str.begin(), str.end())) { cout << str << endl; } return 0; }

運行結果如下:

 

在使用稍大數據測試的時候,發現標准C++的效率很差,換成C函數寫一下,效率提升了許多倍,比如我用字符序列“aabbddef”作為測試,上面C++代碼用了6s,而下面的C代碼只用了0.918s。所以,平時寫代碼時能用C就用C。

 

#include <stdio.h> #include <algorithm>

using namespace std; int main() { char str[200]; int len; puts("Please Input letter sequence: "); gets(str); len = strlen(str); // 必須先排序
    sort(str, str + len); puts("Permutation result: "); puts(str); while(next_permutation(str, str + len)) { puts(str); } return 0; }

 


免責聲明!

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



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