矢量矢量作为高效的数据结构; std :: vector <std :: vector <sometype>&gt;

时间:2016-01-14 07:55:16

标签: c++ c++11 boost vector

我正在寻找可以在一个向量中存储多个向量的数据结构,而不会有碎片或任何性能问题。

现在这样做

std::vector< std::vector<SomeType> > myMultiVector;

会有所帮助,但是根据我的理解,内存会变得支离破碎,因为显然 myMultiVector 中的每个向量都不会位于连续的空间中,因为它的分配方案。

这不是用于创建从一开始就知道尺寸或尺寸的数组。各个方向的尺寸都是动态的。我想要的是一个像那样的结构,其中分配的大小是连续的。我希望能够在向量向量和每个向量本身上执行 push_back() resize()之类的操作。矢量的大小应该能够不同。

我一直在看看Boost :: Multiarray。似乎很有希望,但不想要一个阵列,我想要一些dyanmic的东西。我仍然不确定,但如果以有效的方式改变尺寸,我可以改变尺寸。所以也许Boost :: Multiarray就是答案。

我一直在考虑使用 std :: multimap 甚至 std :: unordered_multimap 并使用键作为索引,因为内部排序和散列I&# 39;虽然分配空间应该是连续的,但我不确定它是否是正确的结构。

使用 std :: vector&lt; std :: vector&gt; myMultiVector; 适用于我需要的东西,但我觉得优化错失了机会。

您知道哪些其他替代品可以帮助提供更有效的载体载体?让我知道: - )

注意:我知道问题与此处提出的问题非常相似。我只是要求替代方案不能解决特定问题。

4 个答案:

答案 0 :(得分:5)

听起来你想要的不同东西相互排斥。如果你想在每个子向量中具有大小灵活性,同时让所有数据在内存中很好地对齐,你基本上被迫为所有向量重新分配内存,并在每次更改大小时进行大量复制任何子向量。因此,与std::vector< std::vector<SomeType> >保持联系可能更好。如果你需要在每次调整大小操作之间使用固定大小的向量进行大量高效操作,你可以考虑创建一个复制所有数据的中间数组。

您还应该考虑您对绩效的担忧是否会在实践中产生影响。除非您注意到使用std::vector< std::vector<SomeType> >确实会显着影响您的表现,否则您可能不会担心它。

所以直接回答你的问题:我认为根据你的需要可能没有更好的数据类型,因为你提出的那个已经完全正常了。

答案 1 :(得分:0)

std::multimap / std::unordered_multimap肯定不会做你想要的。每个人SomeType将在其自己的分配中(比向量向量更糟)。

我认为你不会找到一个你想要的预制类型 - 你将自己编写它(可能是通过包装一个std::vector,然后提供理解它的智能迭代器这个特定载体的范围)。请注意,my_magic.front().push_back(...)必须插入到支持向量的中间,然后将所有内容洗牌(尽管vector :: insert会为您进行洗牌)。

就个人而言,如果值得,我会感到惊讶。

答案 2 :(得分:0)

如果你小心使用它,你总是可以使用仿函数将1D矢量实现为2D矢量:

template <typename T>
class Vector2D : public std::vector<T>
{
protected:
    unsigned _width;
public:
    unsigned width() {return _width;}
    void setWidth(unsigned i) {width = i;}

    T& operator()(int x, int y) {
        return this->operator[](x + _width * y);
    }

    Vector2D(unsigned newWidth = 10) : std::vector<T>(), _width(newWidth) {}
};

允许您执行以下操作:

int main() {
    Vector2D<int> vec(10);
    vec.resize(100, 0);

    vec(6, 7) = 3;

    int some_number = vec(6, 7);

    cout << some_number: //Output: 3
}

这种方法的优点是数据是连续的,但可以用二维语义进行操作。

答案 3 :(得分:-2)

我建议使用自己的容器。我将给你一个抽象的想法:

class MyOwn2D{
MyOwn2D(int rows,int cols):rows(rows),cols(cols),data(std::vector<SomeType>(rows*cols){}
SomeType& get_element(int i,int j){
    return data[i*rows+j];
}
private:
    int rows,cols
    std::vector<SomeType> data;
};

上一个例子是假的。 operators overloading您需要更好的内容,并且可能需要proxy[][] operator(更像2D array)。所以,我只是提出了它的想法。祝你好运!