【发布时间】:2018-06-02 17:27:21
【问题描述】:
我有一组 64 位整数,我需要在其上应用一定数量的“对称运算”。对称操作只是一系列位排列,以 {i0,i1,i2,..} 形式存储在 int 的向量中,其中 bit[0]->bit[i0], bit[1]->bit[i1 ],等等...实际上,我只是使用前 N 位,其中 N 是在运行时确定的,但原则上可以达到 64。
例如,我正在使用 N=4,输入是整数 3 或 0011,并且我有 4 个对称操作存储在向量对称操作的向量中
symmetry_ops[0] = {0,1,2,3};
symmetry_ops[1] = {1,2,3,0};
symmetry_ops[2] = {2,3,0,1};
symmetry_ops[4] = {3,0,1,2};
我想要一个函数,它返回通过将这些操作应用于 3 获得的 4 个整数,即 0011、0110、1100 和 1001。这个例子很简单,但实际上排列可能比仅仅移动到离开了。
我编写了以下简单(天真的?)代码:
std::vector<unsigned long> apply_symmetries(const std::vector<std::vector<unsigned> > &symmetry_ops, unsigned long state)
{
unsigned N = symmetry_ops[0].size();
std::vector<unsigned long> s_moved(symmetry_ops.size(),0);
for (unsigned i = 0; i < N; i++) {
unsigned long s_i = (state&(1UL<<i))>>i; // extracts bit i in state
for (unsigned op = 0; op != symmetry_ops.size(); op++)
s_moved[op] = s_moved[op]|(s_i<<symmetry_ops[op][i]);
}
return s_moved;
}
它对整数“状态”执行所有对称操作。我只是在 i 上的循环中一个接一个地进行,首先将其存储在 s_i 中,然后为每个对称操作移动它。
知道,这是我的程序中最耗时的部分之一,因为典型的大小是 ~100-200 对称操作,适用于 ~10^10 整数,N 约为 40。代码正常工作,但我想知道这个功能是否可以优化?
提前致谢。
【问题讨论】:
标签: c++ bit-manipulation