我有一个函数(由其他人编写),它基于一组组件构建组合。不知何故,它涉及按位移位操作,但我很难理解它。代码如下所示:
// Declarations in the header file.
vector<set<Component*, compareComponentIDs>> allScenarios;
// The function.
void System::buildAllScenarios()
{
int x, y;
for (x=1; x < (1 << (int)components.size()); x++){
set<Componenet*, compareComponentIDs> curScenario;
for(y=0; y < (int)components.size(); y++){
if ((x >> y) & 1){
curScenario.insert(components[y]);
}
}
allScenarios.push_back(curScenario);
}
return;
}
让我们说组件的数量是10.然后,我认为第一个for循环将循环20次,因为左移位将使组件数乘以2.第二个组件将循环通过10次,因为没有特殊操作。我不知道if语句正在评估什么。
有了这些信息,我的问题是:
任何帮助都将不胜感激。
答案 0 :(得分:1)
第一个循环实际上会循环1 * 2 ^ 10-1次,因为它是1被移位而不是10。那就是1023.(x从1开始,而不是0)
第二个循环将循环10次循环。
该行
curScenario.insert(components[y]);
将运行多次,因为在x中设置了位。 因此,如果x为100101,则该行将运行3次。
当我弄清楚这是怎么做你想要的时候,我会编辑这个。
答案 1 :(得分:1)
您有n个可能的组件。在一个场景中,每个组件是否在(2个值)中。提示你有2 ^ n个潜在的场景。例如,对于3个组件,您有2 * 2 * 2 = 8种可能性。
n的第一次二进制移位相当于2 ^ n的多次移位(参见iso std 5.8节)。因此外部循环遍历每个场景。如果以二进制编写每个数字,则将其写入n位,每个位代表一个组件。例如:
0: 000 no component
1: 001 first component in
2: 010 second component in
3: 011 first and second component in, etc...
内部循环根据此逻辑解码场景的编号。向右移位y位意味着使位y成为最后一位。 x&amp; 1表示仅查看最后一位。它会在与每个组件对应的位上lloks:如果它是0(组件不在)或1(组件在内)。在后一种情况下,它将组件插入一组中。
非常聪明有效的算法,只要组件少于int 中的位。为了避免与符号位相关的未定义行为,如果你有sizeof(int)* 8组件,我建议使用无符号int rather
而不是int
。
答案 2 :(得分:1)
该语句称为按位AND ,并检查2个操作数中的相应位,如果两者都为1则评估True
。
因为1位空间(<< 1
)的位移相当于乘以2(例如,十进制系统中的移位等于乘以10)。
另外,如果我可能:这对我来说是代码味道 - 有人试图通过按位操作变得聪明,没有意识到编译器正在进行所有优化工作。除非针对非常特定的硬件(如用C语言完成)进行编程,否则在查看丢失的可读性时,性能提升(如果有的话)会下降。
答案 3 :(得分:0)
第二个for循环中的if语句如何工作?它做了什么?
x >> y
将x
,y
个位置向右移位。
&
是按位和运算符。因此(x >> y) & 1
如果0
的结果为偶数,则结果为(x >> y)
,如果结果为奇数,则结果为{
为什么第一个for循环迭代次数比组件数多两倍?
2^components.size()
次。 1 << (int)components.size()
会将左侧的位(即1
)components.size()
位置向左移动。这相当于说2^(components.size())
。
与您的代码实际执行的操作相关的结果,即计算方案的功率集。