9

我很难理解如何初始化向量向量。

typedef 向量<向量<向量<向量<浮点数>>>>数据容器;

我希望这符合

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;

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

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

4

3 回答 3

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

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

问题std::vector在于它 (a) 是可调整大小的,并且 (b) 丝毫不关心它的内容,只要它们是正确的类型。这意味着,如果您有vector<vector<int> >,那么所有“行向量”都必须维护它们自己的单独簿记信息,了解它们的长度——即使您想强制它们的长度相同。这也意味着它们都管理单独的内存分配,这会损害性能(缓存行为),并且由于如何std::vector重新分配而浪费更多空间。boost::multi_array设计时期望您可能想要调整它的大小,但不会通过在末尾附加元素(行,对于二维数组/面,对于 3 维数组/等)来不断调整它的大小。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

因为“默认构造”的 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的unnamed,用于初始化default d2,用于初始化default d3,用于初始化result

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

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

  • 您可以使用 预先调整向量的大小.resize(),然后正常索引到它(最多为您调整大小的数量)。

于 2010-12-01T00:37:24.863 回答
2

您可能必须设置大小或保留内存

你能做一个 for-each 还是一个嵌套的 for 会调用

myVector.resize(x); //or size

在每个级别上。

于 2010-12-01T00:19:34.397 回答
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;
}
于 2010-12-01T00:46:21.760 回答