2010-12-01 194 views
6

我有一个艰难的时间让我的头缠绕如何初始化矢量向量。矢量初始化向量

typedef vector < vector < vector < vector < float >> 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.

难道我psyching自己了,或者这是一样简单

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

它似乎并不像,应该工作。不知何故顶级矢量必须先被初始化。

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

回答

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

  • 不要使用嵌套向量如果你的存储必须矩形,即你可以调整尺寸的一个或多个,但每个“行”必须在某一点相同的长度。使用boost::multi_array。这样一来,你的文件“此存储是矩形”,节省空间的大量,仍然可以得到调整大小的能力,有实物福利等

事情有关std::vector的是,它(一)是可以调整大小的,(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 

因为“默认构造” 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()结果转换为您在Next-innermost循环之前创建的d2,依此类推。

  • 您可以事先用.resize()预先调整矢量大小,然后将其正常编入索引(达到您调整的大小)。

+0

那里有整洁的建筑。我会给一个提高multi_array一枪。感谢您的深入解答。 – ValenceElectron 2010-12-01 01:04:18

+2

在新的C++标准中,`boost :: array`的功能由标准库中的`std :: array`提供。 – 2012-12-21 14:39:57

0

你可能将不得不设置大小或备用内存

你能否做的for-each或一个嵌套这将要求

myVector.resize(x); //or size 

每个级别上。

+0

.size()检查矢量的当前大小。你想.resize()。 – 2010-12-01 00:37:54

1

编辑:我承认这段代码并不优雅。我喜欢@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; 
}