C ++中的稀疏向量?

时间:2014-06-02 21:38:02

标签: c++ stl

我有一些代码,使用类向量,我想用一个实现稀疏向量的向量来实现(即不是将元素记录在向量长度的数组中,包括0' s ,它只包括查找表中的非零表。)

C ++中是否有任何稀疏矢量类使用与矢量相同的接口? (这将使重构变得更加容易。)

2 个答案:

答案 0 :(得分:7)

Brendan认为逻辑上矢量提供从索引到值的映射是正确的。 std::vector使用简单数组完成此映射。但还有其他选择。

  • std::unordered_map已摊销O(1)次操作,似乎是一种自然的选择。
  • std::map具有O(logn)操作,但常量较小,并且在此背后有更多年的优化。在实践中,它可能会更快,具体取决于您的应用程序。
  • SparseHash具有与STL兼容的哈希表实现,声称优于标准unordered_map
  • C++ BTree再次提供与STL兼容的map,但使用btree而不是二叉树。他们声称显着improved memory (50-80%) and time
  • BitMagic提供了稀疏向量的实现。想一个稀疏的std::bitset。如果这符合您的需求,它会提供比所有其他方法更大的改进。
  • 最后,稀疏向量的经典方法是使用两个向量,一个用于索引,一个用于值。所以你有一个std::vector<uint> ind;和一个std::vector<value_type> val;

其中没有一个与<{1}}完全相同,但差异非常小,您可以轻松编写一个小包装器。例如,对于地图类,您需要跟踪大小并重载std::vector以返回该数字而不是非空元素的数量。实际上,Brendan链接到的Boost的mapped_vector就是这样的:它在类似矢量的界面中包含类似地图的类。

在所有情况下都可以使用直接替换(因为size()几乎在所有情况下都被假定为退化为数组,例如std::vector,并且通常此使用)。大多数对稀疏案例感兴趣的用户也对利用稀疏性感兴趣,因此需要暴露。例如,稀疏向量的迭代器必须遍历所有元素,包括空白,这简直是浪费。稀疏结构的重点是跳过所有这些。如果你的算法无法处理,那么你就会在桌面上留下很多潜在的收益。

答案 1 :(得分:4)

Boost有一个sparse vector。我不认为标准库中存在一个。

从长远来看,

std::unordered_map可能是一个更好的选择,除非你已经在使用Boost。重构的主要烦恼是size()意味着地图与稀疏数组不同。基于范围的for循环应该可以更容易处理。