繁体   English   中英

位操作,置换位

[英]Bit manipulation, permutate bits

我试图创建一个循环遍历所有不同的整数,其中最后40位中的10个被设置为高,其余设置为低。 原因是我有一个包含40个不同值的地图,我想总结所有不同的方式,其中十个这些值可以相乘。 (这只是出于好奇,所以它真的是“bitmanip”-loop感兴趣,而不是这样的总和。)

如果我用例如4比特中的2比特来做这个,那么手动设置全部都很容易,

0011 = 3,
0101 = 5,
1001 = 9,
0110 = 6,
1010 = 10,
1100 = 12,

但是在40个中有10个我似乎找不到有效生成这些方法的方法。 我试过,从1023(=二进制的1111111111)开始,找到了一个很好的方法来操纵它,但没有成功。 我一直在尝试用C ++做这件事,但它确实是感兴趣的一般方法(如果有的话)。 我做了一些谷歌搜索,但没有成功,如果有人有一个很好的链接,那当然也会受到赞赏。 :)

您可以使用选择/组合算法的任何标准实现。 基本上你想要选择40位中的10位,将其设置为1

也就是说, 40选10是847,660,528 然而,这个数字将乘以不在前40位的许多可能的“尾部”位。据推测,尾部位不受任何规则的约束,因此如果有k位,那么这将是另一个2 k因子。

即使你实现它,这个算法也会很慢。 想一个更好的方法来解决你遇到的任何问题可能是一个好主意。

相关问题

你可以简单地使用next_permutation 这是一个重现你的2个案例的示例(订单略有不同):

#include <iostream>
#include <algorithm>
using namespace std;
int main () {
 int bits[] = {0,0,1,1};

 do {
  for (int i = 0; i < 4; ++i) cout << bits[i] << " ";
  cout << endl;
 } while ( next_permutation (bits,bits+4) );
 return 0;
}

有点复杂,但纯粹是通过位操作完成的。 你的例子:

#define WIDTH 4
#define BITS 2

void printbits(long pattern) {
  long bit;
  for (bit = 1L << WIDTH - 1; bit; bit >>= 1)
    putchar(pattern & bit ? 49 : 48);
  putchar('\n');
}

void movebits(pattern, bit) {
  long mask = 3L << bit;
  while (((pattern ^= mask) & mask) && (mask < 1L << WIDTH)) {
    mask <<= 1;
    printbits(pattern);
    if (bit)
      movebits(pattern, bit - 1);
  }
}

int main() {
  long pattern = (1L << BITS) - 1L, mask;
  printbits(pattern);
  movebits(pattern, BITS - 1);
}

你的真实应用:

#define WIDTH 40
#define BITS 10

并且,正如polygenelubricants所说,准备等待一点:)当然,你将用printbits用的东西替换printbits ...

(编辑测试不充分:/该死的错字...)

有一种非常明显的方法可以有效地做到这一点:Gosper的方法是从HAKMEM项目175中找到具有相同数量的1位的下一个更高的整数。

lowest_1_bit = prev_combo & -prev_combo;
tmp = prev_combo + lowest_1_bit;
new_combo = (((prev_combo ^ tmp) >> 2) / lowest_1_bit) | tmp;
  • 第一行找到最右边的1位;
  • 第二个将最右边的1位运行转为0 ,将运行左边的0转为1 ;
  • 第三行替换第二行丢失的1位,位于单词的底部。

现在(假设您使用的是64位整数类型),您可以从1023开始,然后重复应用它(直到结果超过1<<40 )。

如果将其重写为一组表示位位置的嵌套循环,则会更容易:

0011 = 0 1
0101 = 0 2
1001 = 0 3
0110 = 1 2
1010 = 1 3
1100 = 2 3

也就是说,第一位的位置P1从0到3-1,第二位P2的位置从P1 + 1到3重复运行。将其转换为通用递归函数作为练习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM