c++中的超长数组

Super long arrays in C++

本文关键字:数组 c++      更新时间:2023-10-16

我有两个集合A和b。集合A包含唯一的元素。集合B包含所有元素。B中的每个元素都是一个10 × 10的矩阵,其中所有的元素不是1就是0。我需要扫描集合B,每次我遇到一个新的矩阵,我就把它加到集合a中。因此集合a是B的一个子集,它只包含唯一的矩阵。

看起来您可能真的正在寻找一种管理大型稀疏数组的方法。简单地说,您可以使用散列映射,将大索引作为键,将数据作为值。如果你多谈谈你的问题,我们也许能找到一个更合适的数据结构来解决你的问题。

更新:

如果集合B只是一个矩阵的集合,而不是所有可能的10x10二进制矩阵的集合,那么你只想要一个稀疏数组。每次找到一个新矩阵时,都要计算它的键(可以简单地将矩阵转换为100位二进制值,甚至是100个字符串!),然后查找该索引。如果不存在这样的键,则为该键插入值1。如果键确实存在,则增加并重新存储该键的新值

下面是一些代码,可能不是很有效:

# include <vector>
# include <bitset>
# include <algorithm>
// I assume your 10x10 boolean matrix is implemented as a bitset of 100 bits.
// Comparison of bitsets
template<size_t N>
class bitset_comparator
{
    public :
      bool operator () (const std::bitset<N> & a, const std::bitset<N> & b) const
      {
          for(size_t i = 0 ; i < N ; ++i)
          {
              if( !a[i] && b[i] )       return true ;
              else if( !b[i] && a[i] )  return false ;
          }
          return false ;
      }
} ;
int main(int, char * [])
{
    std::set< std::bitset<100>, bitset_comparator<100> > A ;
    std::vector< std::bitset<100> >                      B ; 

    // Fill B in some manner ...
    // Keeping unique elements in A
    std::copy(B.begin(), B.end(), std::inserter(A, A.begin())) ;
}

可以用std::list代替std::vector。B中元素的相对顺序在A中不保留(A中的元素已排序)。

编辑:我在我的第一篇文章中颠倒了A和B。现在是正确的。很抱歉给您带来不便。我还更正了比较函子

B中的每个元素都是一个10 × 10的矩阵,其中所有元素的值要么为1,要么为0。

很好,这意味着它可以用一个100位的数字表示。让我们把它四舍五入到128位(16字节)。

一种方法是使用链表——创建一个像(在C中)这样的结构:
typedef struct sNode {
    unsigned char bits[16];
    struct sNode *next;
};

和维护整个列表B作为一个排序链表。

性能会比(a)使用100位数字作为数组索引到一个真正巨大的(给定已知宇宙的大小,这是不可能的)数组要低一些。

当需要在B中插入新项时,将其插入到所需的位置(在相等或更大的项之前)。如果它是一个全新的(如果你之前插入的是不同的,你就会知道),也把它添加到A


(a)虽然可能不是难以管理,但您可以采取一些选项来提高速度。

一种可能性是使用跳跃表,以便在搜索过程中更快地遍历。这是另一个指针,它不是引用下一个元素,而是引用一个10(或100或1000)个元素。这样,您就可以相当快地接近所需的元素,并在该点之后进行一步搜索。

或者,因为你谈论的是位,你可以把B分成(例如)1024个子B列表。使用100位值的前10位来确定您需要使用哪个子B,并仅存储接下来的90位。仅这一点就可以使搜索速度平均提高1000(如果需要改进,请使用更多的前导位和更多的子B)。

你也可以在100位的值上使用哈希来生成一个更小的键,你可以用它作为数组/列表的索引,但我不认为这会给你任何真正的优势,在前一段的方法

将每个矩阵转换为100位二进制数字的字符串。现在通过Linux实用程序运行它:

sort | uniq

如果你真的需要在c++中这样做,可以实现你自己的归并排序,那么uniq部分就变得微不足道了。

您不需要N个桶,其中N是所有可能输入的数量。二叉树就可以了。这是用c++中的set类实现的。

vector<vector<vector<int> > > A; // vector of 10x10 matrices
// fill the matrices in A here
set<vector<vector<int> > > B(A.begin(), A.end()); // voila!
// now B contains all elements in A, but only once for duplicates