使用位实现集合

时间:2014-10-17 14:04:51

标签: c++ algorithm bitwise-operators

我正在阅读关于在以下位置表示位的集合

http://www.brpreiss.com/books/opus4/html/page395.html

class SetAsBitVector : public Set

{

   typedef unsigned int Word;

   enum { wordBits = bitsizeof (Word) };


   Array<Word> vector;


public:

    SetAsBitVector (unsigned int);

    // ...

};

SetAsBitVector::SetAsBitVector (unsigned int n) :
    Set (n),

                                                     vector ((n + wordBits - 1U) / wordBits)
{
  // Question here?
   for (unsigned int i = 0; i < vector.Length (); ++i)

    vector [i] = 0;

}

void SetAsBitVector::Insert (Object& object)
{

   unsigned int const item = dynamic_cast<Element&> (object);

   vector [item / wordBits] |= 1 << item % wordBits;
  // Question here
}
  

要将项目插入集合,我们需要更改相应的位   在比特数组中。位阵列的第i位是位i mod   字天花板(i / w)。因此,使用执行Insert函数   按位或将第i位更改为1的操作,如上所示   计划。即使它稍微复杂一点   SetAsArray类的相应操作,运行时间为   这个操作仍然是O(1)。因为w = wordBits是2的幂,所以   可以替换除法和模运算,/和%,   像这样的轮班和面具:

     

vector [item&gt;&gt; shift] | = 1&lt;&lt; (item&amp; mask);

     

根据编译器和机器架构,这样做可能   通过常数因子

提高Insert操作的性能

问题

  1. 我在构造函数中的问题为什么作者将wordBits添加到“n”并减去1,而我们可以直接用作n / wordbits?

  2. 第二个问题whay作者的意思是声明“ince w = wordBits是2的幂,有可能用这样的移位和掩码替换除法和模运算,/和%:

  3. vector [item&gt;&gt; shift] | = 1&lt;&lt; (item&amp; mask);

    如果出现上述情况,请提供一个示例,其中包含shift和mask的值。

    1. 为什么作者提到取决于架构和编译器,性能有所提高?

1 个答案:

答案 0 :(得分:2)

我将其重新标记为C ++,因为它显然不是C。

  1. 围捕。考虑如果您使用n等于小于wordBits的小号来调用它会发生什么。通用公式正是所使用的公式,即b = (a + Q - 1) / Q确保b * Q至少为a
  2. 基本的二进制算术,除以2相当于向右移动等等。
  3. 在某些机器上,像移位和蒙版这样的按位操作比分区和模数更快。