【发布时间】:2015-07-29 08:18:10
【问题描述】:
我想以位表示生成所有可能的组合(不重复)。我不能使用任何库,如 boost 或 stl::next_combination - 它必须是我自己的代码(计算时间非常重要)。
这是我的代码(由 StackOverflow 用户修改):
int combination = (1 << k) - 1;
int new_combination = 0;
int change = 0;
while (true)
{
// return next combination
cout << combination << endl;
// find first index to update
int indexToUpdate = k;
while (indexToUpdate > 0 && GetBitPositionByNr(combination, indexToUpdate)>= n - k + indexToUpdate)
indexToUpdate--;
if (indexToUpdate == 1) change = 1; // move all bites to the left by one position
if (indexToUpdate <= 0) break; // done
// update combination indices
new_combination = 0;
for (int combIndex = GetBitPositionByNr(combination, indexToUpdate) - 1; indexToUpdate <= k; indexToUpdate++, combIndex++)
{
if(change)
{
new_combination |= (1 << (combIndex + 1));
}
else
{
combination = combination & (~(1 << combIndex));
combination |= (1 << (combIndex + 1));
}
}
if(change) combination = new_combination;
change = 0;
}
其中n - 所有元素,k - 组合元素的数量。
GetBitPositionByNr - 返回第 k 位的位置。
GetBitPositionByNr(13,2) = 3 原因 13 是 1101,第二位在第三位。
它为n=4, k=2 提供了正确的输出,即:
0011 (3 - decimal representation - printed value)
0101 (5)
1001 (9)
0110 (6)
1010 (10)
1100 (12)
它还为k=1 和k=4 提供了正确的输出,但为k=3 提供了错误的输出,即:
0111 (7)
1011 (11)
1011 (9) - wrong, should be 13
1110 (14)
我猜问题出在内部 while 条件(第二个),但我不知道如何解决这个问题。
也许你们中的一些人知道我想要实现的更好(更快)算法?它不能使用额外的内存(数组)。
这是在 ideone 上运行的代码:IDEONE
【问题讨论】:
-
查看经典算法:graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation;必须以
(1 << n) - 1开头,其中n是位数;请注意,重复以全1结束。 -
非常感谢,这是我一直在寻找的。span>
-
@AkiSuihkonen 为什么要评论而不是回答?!
-
Q 不是很清楚——但这里已经回答了很多次了,我认为从新的答案中获得更多代表是可以的:stackoverflow.com/search?q=next+bit+permutation
标签: c++ algorithm bit-manipulation combinations