2010-12-01 229 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; 
}