[英]Generate permutation using bitmask
我正在使用位掩碼生成字符串的所有排列。
void recurse(string s, int mask,int taken){
if(taken == n){
cout << " ";
return;
}
for(int i = 0; i < n; i++){
if(((1 << i) & mask) == 0){
cout << s[i];
recurse(s, (mask|(1 << i)), taken + 1);
}
}
}
在這個函數中,n 是字符串的長度。 我正在使用 take 變量跟蹤到目前為止打印了多少個字符。 在我調用的主函數中
recurse(s,0,0);
但這不能正常工作。 對於輸入
紅色
它的輸出是
紅鹿博士 德雷爾博士
我哪里出錯了?
更新// 下面的代碼工作正常。
void recurse(string s, int mask,int taken, string pref){
if(taken == n){
cout << pref <<endl;
return;
}
for(int i = 0; i < n; i++){
if(((mask >> i) & 1) == 0){
recurse(s,(mask | (1 << i)),taken + 1, pref + s[i]);
}
}
}
其實,提問者自己給出了答案。 (恭喜。)
由於我已經開始擺弄(無法抗拒),我也想提出我的解決方案:
#include <iostream>
#include <string>
using namespace std;
void recurse(
const string &s, unsigned mask = 0, const string &out = string())
{
size_t n = s.size();
if (out.size() == n) cout << ' ' << out;
for (size_t i = 0; i < n; ++i) {
unsigned bit = 1 << i;
if (mask & bit) continue;
recurse(s, mask | bit, out + s[i]);
}
}
int main()
{
string test = "red";
recurse(test);
cout << endl;
return 0;
}
編譯和測試:
red rde erd edr dre der
recurse()
遍歷s
所有字符,尋找mask
尚未標記為已取的字符。 每個找到的字符都被添加到輸出out
。 然后,遞歸調用對所有未使用的字符重復它。
自己在ideone上查看示例代碼。
您的第一個代碼是訪問該樹的每個節點一次並打印一個字符。 所以它給出了錯誤的輸出。
另一方面,您使用了一些冗余變量。
你應該使用s.size()
而不是n
。
在第二個代碼中taken
您應該使用pref.size()
而不是pref.size()
。
這是另一個版本。 它在兩個方面與提問者的代碼不同:
參數taken
可以被省略,並且我們可以使用mask + 1 == (1 << n)
而不是。 它基本上檢查,如果位1
到n-1
的mask
全部為1。 如果是,則遞歸深度為n
,我們打印排列。
如果字符串的大小很大,則在每次迭代中復制string pref
可能會很慢。 我們可以改為使用引用。
#include <iostream>
#include <string>
using namespace std;
void recurse(string s, int mask, string &pref);
int n = 3;
int main()
{
string pref("");
recurse(string("abc"), 0, pref);
return 0;
}
void recurse(string s, int mask, string &pref)
{
if (mask + 1 == (1 << n)) {
cout << pref << endl;
return;
}
for (int i = 0; i < n; i++) {
if (((mask >> i) & 1) == 0) {
pref += s[i];
recurse(s, (mask | (1 << i)), pref);
pref.erase(pref.end() - 1);
}
}
}
其中n
是字符串的大小。 輸出是
abc
acb
bac
bca
cab
cba
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.