[英]Generate permutation using bitmask
I am generating all permutations of a string 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);
}
}
}
In this function n is the length of the string.在这个函数中,n 是字符串的长度。 I am keeping track of how many characters are printed so far using taken variable.
我正在使用 take 变量跟踪到目前为止打印了多少个字符。 In the main function I am calling
在我调用的主函数中
recurse(s,0,0);
But this is not working correctly.但这不能正常工作。 For input
对于输入
red
红色
Its output is它的输出是
red de erd dr dre er
红鹿博士 德雷尔博士
Where I am going wrong?我哪里出错了?
UPDATE // Below code works fine.更新// 下面的代码工作正常。
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]);
}
}
}
Actually, the questioner provided the answer himself.其实,提问者自己给出了答案。 (Congratulation.)
(恭喜。)
As I already started to fiddle (couldn't resist) I want to present my solution as well:由于我已经开始摆弄(无法抗拒),我也想提出我的解决方案:
#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;
}
Compiled and tested:编译和测试:
red rde erd edr dre der
recurse()
iterates through all characters of s
looking for one which is not already marked in the mask
as taken. recurse()
遍历s
所有字符,寻找mask
尚未标记为已取的字符。 Each found characters is added to output out
.每个找到的字符都被添加到输出
out
。 Then, the recursive call repeats it for all untaken characters.然后,递归调用对所有未使用的字符重复它。
Check out the sample code yourself on ideone .自己在ideone上查看示例代码。
Permutation tree for 'abc' 'abc' 的排列树
Your first code was visiting each node of this tree once and printing a character.您的第一个代码是访问该树的每个节点一次并打印一个字符。 So it was giving wrong output.
所以它给出了错误的输出。
On a different note, you have used some redundant variables.另一方面,您使用了一些冗余变量。
Instead of n
you should use s.size()
.你应该使用
s.size()
而不是n
。
In the second code instead of taken
you you should use pref.size()
.在第二个代码中
taken
您应该使用pref.size()
而不是pref.size()
。
Here is another version.这是另一个版本。 It's different from the questioner's code in 2 ways:
它在两个方面与提问者的代码不同:
The parameter taken
can be omitted and we can use mask + 1 == (1 << n)
instead.参数
taken
可以被省略,并且我们可以使用mask + 1 == (1 << n)
而不是。 It basically checks if bits 1
to n-1
of mask
are all 1's.它基本上检查,如果位
1
到n-1
的mask
全部为1。 If so, then the recursion depth is n
and we print the permutation.如果是,则递归深度为
n
,我们打印排列。
Copying the string pref
in each iteration can be slow if the size of the string is large.如果字符串的大小很大,则在每次迭代中复制
string pref
可能会很慢。 We can instead use a reference.我们可以改为使用引用。
#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);
}
}
}
where n
is the size of the string.其中
n
是字符串的大小。 The output is输出是
abc
acb
bac
bca
cab
cba
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.