我正致力于解决此问题的方法: 给定0和1的量,生成包含0和1的所有可能组合的列表。
示例:如果我们有一个1和两个0,算法将返回
001
010
100
问题是经典组合算法没有针对此目的进行优化。 这是非优化组合算法返回的结果:
001
001
010
010
100
100
如您所见,所有组合都重复两次,因为0被解释为不同的元素。
如何使用算法生成输入0和1数的可能组合列表,而不重复组合?
PS:这将在Javascript中使用
编辑:解决了!使用@Batch方法。
function combin(o, i)
{
if (o == 0 && i > 0)
{
for (var j = 0, s = ''; j < i; j++)
{
s += '1';
}
return [s];
}
else if (i == 0 && o > 0)
{
for (var j = 0, s = ''; j < o; j++)
{
s += '0';
}
return [s];
}
else if (i == 0 && 0 == o)
{
return [''];
}
else if (i > 0 && o > 0)
{
var l = combin(o - 1, i);
for (var j in l)
{
l[j] = '0' + l[j];
}
var k = combin(o, i-1);
for (var j in k)
{
k[j] = '1' + k[j];
}
return l.concat(k);
}
}
答案 0 :(得分:1)
这是一种方法:从字符串开始,将所有0放在前面。现在将最右边的0移动到最后。然后,将第二个最右边的0个位置向右移动,将最后一个0放在它旁边。再次,将最右边的0移动到最后。将第二个最右边的0向右移动,将最右边的0再次放在它旁边,换班移。一旦你移动了这两个最右边的0对,开始向右移动最右边的0 ....你得到了图片。
示例:三个0,三个1:
000111
001011
001101
001110
010011
010101
010110
011001
011010
011100
100011
100101
100110
101001
101010
101100
110001
110010
110100
111000
不确定如何为此编写一个好的循环,但是一旦你掌握了这个想法,你就可以四处玩耍,如果你愿意,可以尝试找出一个。也许你可以找到一个漂亮的递归,虽然现在不能想到这个方法。
更优雅的方法如下;请注意,使用n
0和m
1生成所有字符串的方法是:
使用0开始字符串,附加n-1
0s和m
1s生成字符串的所有组合,或者使用1开始字符串并附加{{1}生成字符串的所有组合} 0s和n
1s。生成的字符串集是不相交的,因此可以进行简单的递归,而不必担心多次生成字符串。如果您愿意,也可以迭代地进行迭代(迭代生成的字符串的长度,对于迭代i,保持设置为不使用0,使用0,使用i,等等)< / p>
总而言之,递归似乎是找我的方式。基本情况很简单:如果n = 0,你可以获得的唯一字符串是1 ^ m,如果m = 0,你可以获得的唯一字符串是0 ^ n(其中^表示重复)。
如果您想要实现该递归以及测试它(在某种程度上)的方法,请注意您可以生成的字符串数量是m-1
选择n + m
= {{1}选择n
,所以计算你得到的字符串数量会给你一个提示,告诉你你所做的是否按预期工作。不确定javascript是否可以轻松访问二项式系数。
答案 1 :(得分:1)
我认为你想快速做到这一点。如果将0/1模式表示为整数的位,则最小的一个是&#34; 0 ... 01..1&#34;例如0001111如果你有3个0位和4个1位 - 最大的整数是&#34; 1..10..0&#34;。 (例如1111000)。
然后,您的问题是产生按字典顺序的下一位置换(即具有相同数量的1位的下一个整数)的已知问题。
使用http://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation代码的简单实现如下(伪代码):
v = '0..01..1'b // Initialize t as smallest integer of the pattern
while ( t <= '1..10..0'b ):
t = (v | (v - 1)) + 1
v = t | ((((t & -t) / (v & -v)) >> 1) - 1)
print v
请参阅http://www.geeksforgeeks.org/next-higher-number-with-same-number-of-set-bits/及其中的参考资料,以获得有关算法如何运作的更详细说明。