Bitset,bool传染媒介或ints传染媒介简单的大整数的

时间:2017-09-20 21:25:22

标签: c++ vector biginteger bitset std-bitset

我有一个算法,我目前使用两个无符号整数作为位图来存储有关输入的信息;这将最大输入大小限制为64,因此我想创建一个整数被bitset或简单大整数替换的版本。我开始使用vector< bool>写一些东西,但环顾四周,我看到很多答案告诉我要避免矢量< bool>。

我需要的操作:

  • 初始化为全零。
  • 向左移动(乘以2)并设置新的lsb。
  • 添加并设置msb。
  • 首先比较两组以查找最小/词典。

当它们被创建时,我知道最大位数,但起初我只需要1位;然后,在每一步,一组向左移动而另一组将有一个新的最高位:

{
    a <<= 1;
    a[0] = x;
    b[++msb] = y;
    if (a < b) b = a;
} 

如果我创建了大小为1的位集,然后逐渐扩展它们,那么比较可能比我立即将长度设置为最大并且可能有数千个前导零更快?

我应该继续使用vector&lt; bool&gt;或者使用std :: bitset(不幸的是固定大小)或者使用无符号整数向量写一个简单的biginteger实现,只能执行上面提到的操作?

使用vector&lt; bool&gt;你可以用零长度初始化向量:

std::vector<bool> a(0), b(0);

然后执行上面提到的操作:

{
    a.push_back(x);
    b.insert(b.begin(), y);
    if (a < b) b = a;
}

2 个答案:

答案 0 :(得分:4)

我认为boost::dynamic_bitset就是你所追求的目标。

以下是满足您要求的示例:

#include <iostream>
#include <boost/dynamic_bitset.hpp>
int main() {
    boost::dynamic_bitset<> a(3, 2); // a = 010
    a[0] = true;                     // a = 011
    a.push_back(true);               // a = 1011
    boost::dynamic_bitset<> b = a;   // b = 1011
    a <<= 1;                         // a = 0110
    bool aless = a < b;              // true
    unsigned long al = a.to_ulong(); // al = 6
    std::cout << "a=" << a << ", al=" << a.to_ulong() << "\n"
              << "b=" << b << ", bl=" << b.to_ulong() << "\n"
              << "a<b=" << (a<b) << "\n";
}

一些注意事项:

  • 该对象完全是动态的,没有机会利用您对最大尺寸的了解。我相信它甚至不使用小对象优化,所以它总是会分配一些动态内存。
  • 构造函数有点特殊。第一个参数是位数,第二个参数是整数值。这意味着要按照您的要求初始化为单个真实位,您将使用dynamic_bitset<>(1, 1)。遗憾的是,没有initializer_list构造函数,所以你不能只做a = {true}。也许最明显的事情是默认构造对象并在单独的一行上push_back(true)
  • push_back影响最重要的位,即左侧的值。那是因为“front”表示元素0,这是最不重要的位。
  • 左移操作员不会使对象增长,因此要将项目附加到前面,您需要:
    1. a.push_back(false)(你推的价值无关紧要,因为它会在一瞬间被扔掉)。
    2. a <<= 1
    3. a[0] = x如果您想设置新值。
  • to_ulong()仅在对象的元素足够少以适合您平台上的unsigned long时才有效。请注意,它不是unsigned long long,因此即使在64位系统上也可能是32位。
  • 还有其他一些值得一看的有趣方法,例如: any()all()count()

答案 1 :(得分:0)

您描述的操作(将隐式解释省略为整数)实际上是由deque有效提供的操作。如果您可以容忍内存开销,可以使用std::deque<bool>std::list<bool>也可以使用,但会有更高的开销。)

如果开销太大,可以从

开始
struct Bits {
  std::deque<unsigned> deq;
  int ms_free,ls_free;   // unused bits in the two end words
};

并编写方法以在两端推送位(对于右端,如果deq.push_back()则为lsb_free==0,否则将存储到 deq.back()。比较将使用deq.size()ms_free+ls_free来了解如何对齐两个序列。