矢量初始化矢量

时间:2010-12-01 00:16:33

标签: c++ vector initialization deserialization

我很难让我的脑袋围绕如何初始化矢量矢量。

typedef vector<矢量<矢量<矢量<浮动> > > > DataContainer;

我希望这符合

level_1 (2 elements/vectors)
   level_2 (7 elements/vectors)
      level_3 (480 elements/vectors)
         level_4 (31 elements of float)

解决元素不是问题。这应该像

这样简单
dc[0][1][2][3];

问题是我需要用文件中的乱序数据来填充它,以便连续的项目需要放置像

dc[0][3][230][22];
dc[1][3][110][6]; //...etc

所以我需要事先初始化V的V。

我是在惹恼自己,还是像

一样简单
for 0..1
    for 0..6
        for 0..479
           for 0..30
               dc[i][j][k][l] = 0.0;

这似乎不应该起作用。不知何故,必须首先初始化顶级向量。

任何帮助表示赞赏。我相信这一定比我想象的要简单。

3 个答案:

答案 0 :(得分:19)

  • 如果您提前知道的存储空间,请不要使用嵌套向量,即具体原因 >为什么例如第一个索引的大小必须为6,并且永远不会改变。只需使用普通数组。更好的是,使用boost::array。这样,您可以获得拥有普通数组的所有好处(当您进行多维时节省大量空间),以及实现真实对象实例化的好处。

  • 如果您的存储必须是矩形,请不要使用嵌套向量,即您可以调整一个或多个维度的大小,但每个“行”必须在某些时候长度相同。使用boost::multi_array。这样,你记录“这个存储是矩形的”,节省了大量的空间,仍然能够调整大小,有一个真实对象的好处等。

关于std::vector的事情是它(a)意图是可调整大小的,(b)只要它们是正确的类型,就不会轻易关心它的内容。这意味着如果你有一个vector<vector<int> >,那么所有的“行向量”必须保留它们各自的单独的簿记信息 - 即使你想要强制它们都是相同的长度。这也意味着它们都管理单独的内存分配,这会损害性能(缓存行为),并且由于std::vector重新分配的方式而浪费更多空间。 boost::multi_array的设计期望您可能希望调整它的大小,但不会通过附加元素(行,二维数组/面,三维数组/等)来不断调整大小。 ) 到最后。 std::vector旨在(可能)浪费空间以确保操作不会很慢。 boost::multi_array旨在节省空间并将所有内容整齐地整理到内存中。

那说

是的,在索引向量之前,您需要做一些事情。 std::vector不会神奇地导致索引弹出,因为你想在那里存储东西。但是,这很容易处理:

您可以先使用适当的零值初始化向量,然后使用(size_t n, const T& value = T())构造函数替换它们。也就是说,

std::vector<int> foo(10); // makes a vector of 10 ints, each of which is 0

因为“default-construct”int的值为0。

在您的情况下,我们需要通过创建具有适当大小的子向量并让构造函数复制它们来指定每个维度的大小。这看起来像:

typedef vector<float> d1;
typedef vector<d1> d2;
typedef vector<d2> d3;
typedef vector<d3> d4;
d4 result(2, d3(7, d2(480, d1(31))));

也就是说,未命名的d1由大小为31构成,用于初始化默认d2,用于初始化默认d3,用于初始化result

还有其他方法,但如果你只是想要一堆零开始,它们会更加笨拙。但是,如果您要从文件中读取整个数据集:

  • 您可以使用.push_back()附加到矢量。在最里面的循环之前创建一个空的d1,在其中重复.push_back()来填充它。在循环之后,您将.push_back()结果发送到您在下一个最内层循环之前创建的d2,依此类推。

  • 您可以预先使用.resize()调整矢量大小,然后正常编入索引(最多可调整大小)。

答案 1 :(得分:2)

编辑:我承认这段代码并不优雅。我喜欢@Karl的答案,这是正确的方法。

编译并测试此代码。它打印了208320个零,这是预期的(2 * 7 * 480 * 31)

#include <iostream>
#include <vector>

using namespace std;

typedef vector< vector < vector < vector< float > > > > DataContainer;

int main()
{
    const int LEVEL1_SIZE = 2;
    const int LEVEL2_SIZE = 7;
    const int LEVEL3_SIZE = 480;
    const int LEVEL4_SIZE = 31;

    DataContainer dc;

    dc.resize(LEVEL1_SIZE);
    for (int i = 0; i < LEVEL1_SIZE; ++i) {
        dc[i].resize(LEVEL2_SIZE);
        for (int j = 0; j < LEVEL2_SIZE; ++j) {
            dc[i][j].resize(LEVEL3_SIZE);
            for (int k = 0; k < LEVEL3_SIZE; ++k) {
                dc[i][j][k].resize(LEVEL4_SIZE);
            }
        }
    }

    for (int i = 0; i < LEVEL1_SIZE; ++i) {
        for (int j = 0; j < LEVEL2_SIZE; ++j) {
            for (int k = 0; k < LEVEL3_SIZE; ++k) {
                for (int l = 0; l < LEVEL4_SIZE; ++l) {
                    dc[i][j][k][l] = 0.0;
                }
            }
        }
    }

    for (int i = 0; i < LEVEL1_SIZE; ++i) {
        for (int j = 0; j < LEVEL2_SIZE; ++j) {
            for (int k = 0; k < LEVEL3_SIZE; ++k) {
                for (int l = 0; l < LEVEL4_SIZE; ++l) {
                    cout << dc[i][j][k][l] << " ";
                }
            }
        }
    }

    cout << endl;
    return 0;
}

答案 2 :(得分:1)

您可能需要设置大小或保留内存

你可以做一个for-each或嵌套的那个会调用

myVector.resize(x); //or size

每个级别。