C++ 如何生成二进制字符串的所有可能子集?
我有一个问题,我不知道如何解决它 我有一个二进制字符串,我想生成所有可能的二进制子字符串 例如:C++ 如何生成二进制字符串的所有可能子集?,c++,algorithm,C++,Algorithm,我有一个问题,我不知道如何解决它 我有一个二进制字符串,我想生成所有可能的二进制子字符串 例如: input : 10111 output: 10000, 10100,00111,00001,10110 ... 我怎样才能做到这一点,又快又聪明 如果您只希望值低于二进制字符串的数值,请从二进制字符串中减去一个值,直到达到0为止 如果您想要所有可以由该二进制数表示的值,请从可以由该二进制数表示的最大值中减去1,直到得到0 这类问题出现在那些代码katcha网站上没关系——该死的,我忘了你把它放在
input : 10111
output: 10000, 10100,00111,00001,10110 ...
我怎样才能做到这一点,又快又聪明
orig = n;
然后开始迭代这个数和每一个较小的数
while(n--)
但每次迭代时,忽略那些试图将1置于0位置的迭代:
if(n & !orig)
continue;
如果你希望它是稀疏的——就像在很多零和很少的1中一样,你可以使用移位机制。假设你的号码是1000 1001
注意有三个1,对吗?从000数到111
但对于每一次迭代,将比特再次展开:
n&0000 0001 | n使用递归
printsubsets(const string &in, const string &out)
{
if(in.empty())
{
cout<<out<<"\n";
return;
}
if(in[0]=='1')
printsubsets(in.substr(1), out+"1");
printsubsets(in.substr(1), out+"0");
}
printSubset(常量字符串和输入、常量字符串和输出)
{
if(in.empty())
{
不能这样做:
vector<string> submasks(string in)
{
vector<string> out;
out.push_back(string(in.size(), '0'));
for (int i = 0; i < in.size(); ++i)
{
if (in[i] == '0') continue;
int n = out.size();
for (int j = 0; j < n; ++j)
{
string s = out[j];
s[i] = '1';
out.push_back(s);
}
}
return out;
}
矢量子磁盘(字符串输入)
{
矢量输出;
out.push_back(字符串(in.size(),'0');
对于(int i=0;i
该算法执行以下操作:
从只包含空位字符串“00000…”的向量开始
对于输入字符串中的每个1:使用该1集合创建输出向量中每个字符串的副本
我认为这是非常理想的。魔术-但假设位掩码:
subset( int x )
list = ()
for ( int i = x; i >= 0; i = ( ( i - 1 ) & x ) )
list.append( i )
return list
您可以对二进制字符串使用相同的逻辑,尽管它稍微复杂一些。什么是“二进制字符串”?它是否包含ASCII格式的二进制数字,如0x30和0x31?您的示例不显示子字符串,而是某种排列或组合。请提供更多详细信息。对于二进制字符串,我的意思是字符串s="1000001010001"因此,一个只包含零和字符串的字符串:“Bio Bio”,你可能想读一个子集是什么。你不能有一个不是一个集合的子集。如果我理解了你的问题,我不认为你寻找的是一个标准的名字。也许是子面膜?如果你考虑这个位置集合,你可以把它解释成一个集合问题。对于上面的示例,输入集将是(从右到左计数):{0,1,2,4},输出将对应于子集{4},{2,4},{0,1,2},{0},{1,2,4}(编辑:如果我能计数,也会有帮助!)顺便说一句,所有子集的集合就是powerset。因此,您实际上试图生成的是二进制字符串中“set”位集合的powerset。