2010-12-01 27 views
6

मुझे वैक्टर के वेक्टर को प्रारंभ करने के तरीके के बारे में अपने सिर को लपेटने में कठिनाई हो रही है।वेक्टर प्रारंभिक वेक्टर

टाइपपीफ वेक्टर < वेक्टर < वेक्टर < वेक्टर < फ्लोट>>>> डेटाकंटनर;

मैं इस अनुरूप करने के लिए

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

तत्वों को संबोधित करते मुद्दा नहीं है चाहता हूँ। यही कारण है कि समस्या यह है कि मैं डेटा किसी फ़ाइल से आदेश से बाहर आ रही ऐसी है कि लगातार आइटम

dc[0][3][230][22]; 
dc[1][3][110][6]; //...etc 
की तरह कुछ रखा जा करने की जरूरत है के साथ इसे भरने की जरूरत है की तरह

dc[0][1][2][3]; 

कुछ के रूप में सरल किया जाना चाहिए

तो मुझे पहले वी के वी को प्रारंभ करने की आवश्यकता है।

मैं अपने आप को बाहर 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 है आदि

का आकार बदलने की क्षमता है, एक वास्तविक वस्तु होने का लाभ, प्राप्त है कि यह (एक) आकार बदलने योग्य है और (बी) थोड़ी सी में इसकी सामग्री की परवाह नहीं करता है, जब तक वे सही प्रकार के होते हैं। इसका अर्थ यह है कि यदि आपके पास vector<vector<int> > है, तो "पंक्ति वैक्टर" के सभी को अपनी अलग-अलग पुस्तक-रखरखाव जानकारी को कितनी देर तक बनाए रखना चाहिए - भले ही आप यह लागू करना चाहते हैं कि वे सभी एक ही लंबाई हैं।इसका यह भी अर्थ है कि वे सभी अलग स्मृति आवंटन का प्रबंधन करते हैं, जो प्रदर्शन (कैश व्यवहार) को नुकसान पहुंचाता है, और std::vector पुन: आवंटित करने के कारण और भी अधिक जगह बर्बाद कर देता है। boost::multi_array उस उम्मीद के साथ डिज़ाइन किया गया है जिसे आप आकार बदलना चाहते हैं, लेकिन अंत में तत्वों (पंक्तियों, 2-आयामी सरणी/चेहरों के लिए, 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 

क्योंकि एक "डिफ़ॉल्ट-निर्माण" पूर्णांक मूल्य 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() के साथ एक वेक्टर का आकार बदल सकते हैं, और फिर सामान्य रूप से इसमें अनुक्रमित कर सकते हैं (उस राशि तक जिसे आपने आकार दिया है)।

+0

साफ निर्माण वहाँ। मैं एक शॉट mult_array बढ़ावा देंगे। गहराई से जवाब के लिए धन्यवाद। – ValenceElectron

+2

नए सी ++ मानक में, 'बूस्ट :: सरणी' की कार्यक्षमता मानक पुस्तकालय में 'std :: array' द्वारा प्रदान की जाती है। –

0

आप शायद एक आकार या आरक्षित स्मृति

सेट करना होगा यदि आप एक के लिए-प्रत्येक या एक नेस्टेड कि के लिए

myVector.resize(x); //or size 
प्रत्येक स्तर पर

कहेंगे कर सकता है।

+0

। आकार() वेक्टर के वर्तमान आकार की जांच करता है। आप चाहते हैं .resize()। –

1

संपादित करें: मैं मानता हूं कि यह कोड सुरुचिपूर्ण नहीं है। मुझे @ करल जवाब पसंद है जो जाने का सही तरीका है।

यह कोड संकलित और परीक्षण किया गया है। यह 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; 
} 
+0

पोस्टिंग के बाद मुझे लगभग 30 सेकंड का एहसास हुआ। यह काम करना चाहिए लेकिन कार्ल का बूस्ट मल्टी_एरे बेहतर विकल्प की तरह दिखता है। – ValenceElectron