我正在阅读关于在以下位置表示位的集合
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操作的性能
问题
我在构造函数中的问题为什么作者将wordBits添加到“n”并减去1,而我们可以直接用作n / wordbits?
第二个问题whay作者的意思是声明“ince w = wordBits是2的幂,有可能用这样的移位和掩码替换除法和模运算,/和%:
vector [item&gt;&gt; shift] | = 1&lt;&lt; (item&amp; mask);
如果出现上述情况,请提供一个示例,其中包含shift和mask的值。
答案 0 :(得分:2)
我将其重新标记为C ++,因为它显然不是C。
n
等于小于wordBits
的小号来调用它会发生什么。通用公式正是所使用的公式,即b = (a + Q - 1) / Q
确保b * Q
至少为a
。