C ++:组合算法

时间:2014-07-06 17:14:46

标签: c++ algorithm permutation

我有一个函数(由其他人编写),它基于一组组件构建组合。不知何故,它涉及按位移位操作,但我很难理解它。代码如下所示:

// 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语句正在评估什么。

有了这些信息,我的问题是:

  1. 第二个for循环中的if语句如何工作?它做了什么?
  2. 为什么第一个for循环迭代次数比组件数多两倍。
  3. 任何帮助都将不胜感激。

4 个答案:

答案 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)

  1. 该语句称为按位AND ,并检查2个操作数中的相应位,如果两者都为1则评估True

  2. 因为1位空间(<< 1)的位移相当于乘以2(例如,十进制系统中的移位等于乘以10)。

  3. 另外,如果我可能:这对我来说是代码味道 - 有人试图通过按位操作变得聪明,没有意识到编译器正在进行所有优化工作。除非针对非常特定的硬件(如用C语言完成)进行编程,否则在查看丢失的可读性时,性能提升(如果有的话)会下降。

答案 3 :(得分:0)

  

第二个for循环中的if语句如何工作?它做了什么?

  • x >> yxy个位置向右移位。

  • &是按位和运算符。因此(x >> y) & 1如果0的结果为偶数,则结果为(x >> y),如果结果为奇数,则结果为{

  

为什么第一个for循环迭代次数比组件数多两倍?

  • 它实际上不是两倍,而是2^components.size()次。 1 << (int)components.size()会将左侧的位(即1components.size()位置向左移动。这相当于说2^(components.size())。 与您的代码实际执行的操作相关的结果,即计算方案的功率集。