سؤال

أواجه صعوبة في الحصول على رأسي حول كيفية تهيئة متجه المتجهات.

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 مسبقًا.

هل أنا أخرج نفسي أم أن هذا بسيط مثل

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

لا يبدو أن هذا يجب أن يعمل. بطريقة ما ، يجب تهيئة متجهات المستوى الأعلى أولاً.

أي مساعدة موضع تقدير. أنا متأكد من أن هذا يجب أن يكون أبسط مما أتخيله.

هل كانت مفيدة؟

المحلول

  • لو سمحت لا تستخدم المتجهات المتداخلة إذا حجم التخزين الخاص بك معروف في وقت مبكر, ، أي هناك أ سبب محدد لماذا على سبيل المثال ، يجب أن يكون الحجم 6 ، ولن يتغير أبدًا. فقط استخدم صفيف عادي. الأفضل من ذلك ، الاستخدام boost::array. وبهذه الطريقة ، تحصل على جميع فوائد وجود صفيف عادي (وفر كميات هائلة من المساحة عندما تذهب متعدد الأبعاد) ، وفوائد وجود مثيل حقيقي للكائن.

  • لو سمحت لا تستخدم المتجهات المتداخلة إذا كان يجب أن يكون التخزين الخاص بك مستطيلي, ، أي يمكنك تغيير حجم واحد أو أكثر من الأبعاد ، ولكن يجب أن يكون كل "صف" نفس الطول في مرحلة ما. يستخدم boost::multi_array. وبهذه الطريقة ، يمكنك توثيق "هذا التخزين مستطيل" ، وتوفير كميات هائلة من المساحة ولا تزال تحصل على القدرة على تغيير الحجم ، وفوائد وجود كائن حقيقي ، وما إلى ذلك.

الشيء عن std::vector هل من المفترض أن تكون (أ) قابلة للإصلاح و (ب) لا تهتم بمحتوياتها في أدنى ، طالما أنها من النوع الصحيح. هذا يعني أنه إذا كان لديك 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() النتيجة على d2 الذي أنشأته قبل حلقة الخمر التالية مباشرة ، وهلم جرا.

  • يمكنك تغيير حجم المتجه مسبقًا مع .resize(), ، ثم الفهرس فيه بشكل طبيعي (حتى المبلغ الذي قمت بتغيير حجمه).

نصائح أخرى

من المحتمل أن تضطر إلى ضبط حجم أو ذاكرة الاحتياط

هل يمكن أن تفعل ذلك من أجل ذلك أو متداخل لذلك من شأنه أن يتصل

myVector.resize(x); //or size

على كل مستوى.

تحرير: أعترف أن هذا الرمز ليس أنيقًا. أنا أحب @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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top