سؤال

لا شك أن البعض منكم شاهدوا نشرتي الأخيرة، وكل ذلك فيما يتعلق بنفس البرنامج. أظل الركض في مشاكل معها. لإعادة التكرار: لا يزال التعلم، وليس متطورا للغاية، لا يفهم المؤشرات جيدا، وليس أخذ فئة، ولا تفهم مفاهيم OOP على الإطلاق، إلخ. يدمج هذا الرمز فقط ناقلات مرتبة، farray و sarray، إلى واحد فرز المتجه. على الأقل، آمل أن يكون هذا ما يفعله. أخبرني:

    //int num is to find the size of the original vector and
    //build up farray and sarray; not used in the merge process
    int num = original.size() 
    std::vector<int> final;

    std::vector<int>::iterator it = farray.begin();
    std::vector<int>::iterator iter = sarray.begin();

    //farray.size() == (0 thru (num / 2))
    //sarray.size() == ((num / 2) thru num)
    for (;it != farray.end() && iter != sarray.end();) {
        if (*it > *iter) {
            final.push_back(*it);
            it++;
        }    
        else
        {
            final.push_back(*iter);
            iter++;
        }

            if (it == farray.end()) {
                for (int i = 0; iter < sarray.end(); i++) {
                    final.push_back(*iter);
                }
            }

            if (iter == sarray.end()) {
                for (int i = 0; it < farray.end(); i++) {
                    final.push_back(*iter);
                }
            }
        }

أعد كتابة جزء دمج من وظيفة فرز الدمج الخاصة بي حتى ... حسنا، اجعلها تعمل. لدي بالفعل العديد من الأسئلة حول هذا الرمز:

  1. هل هو شكل جيد للمقارنة مع الأمراض المنقولة جنسيا :: المتجهات :: ITEROTONS ITER && iter لآخر الأخير إذا كانت العبارات إذا كانت الحلقة قد تغيرها على مرورها التالي؟
  2. هل سيؤدي قيم ITER وتغييرها في آخر تمريرة في الحلقة ومسمار الرمز الخاص بي؟ سوف يضع الأخير إذا كانت البيانات قبل مقارنة * و * iTer؟
  3. هل تشير وظيفة الأعضاء في النهاية () إلى القيمة الأخيرة من كل ما هو الاتصال به؟ يبدو أنه قد تمتد الماضي بطريقة أو بأخرى.

تحرير: سأرد على جميع الردود غدا، لذلك تحقق مرة أخرى ثم إذا كنت ترغب في سماع المزيد. انها منتصف الليل الماضي. g'night.

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

المحلول

1. من الجيد مقارنة الماسترين الذين هم من نفس الحاوية كشرط حلقة، ولكن هذا منطقي فقط إذا كنت تتحرك واحدة أو غيرها من المحامين في الجزء الزائد إذا كان بيان حلقة أو في الجسم من حلقة حلقة نفسها. في هذا للحلقة التي تقارن iter ضد sarray.end() لكن حلقة لا تتغير أبدا iter. وبعد هذا يعني أنه لن يكون هناك أي تكرارات أو حلقة لن تنهي أبدا. أيضا، ربما تريد استخدامها != و لا < للمقارنة. == و != العمل لجميع المتسابقين، < لا.

            for (int i = 0; iter != sarray.end(); i++) {
                final.push_back(*iter);
            }

كما iter يبدأ حيث تريد أن تبدأ الحلقة، قد ترغب في هذا الأمر:

            for (; iter != sarray.end(); ++iter) {
                final.push_back(*iter);
            }

بما أن كنت لا تزال تتعلم (على الرغم من أننا جميعا جميعا!)، فمن المحتمل أن تكون مفيدة للعمل من خلال خوارزمية مثل هذا، ولكن يجب أن تكون على علم std::merge والتي ربما تفعل ما تريد.

std::merge( farray.begin(), farray.end(), sarray.begin(), sarray.end(), std::back_inserter( final ) );

(تحتاج #include <iterator> و <algorithm>.)

2. لا أرى زيادة ITER أو أنه في الخارج لحلقة إبطال المنطق في وقت لاحق لحلقات، والنقطة في 1. جانبا.

3 . end() يشير إلى جانب واحد في نهاية الحاوية، حتى تتمكن من استخدامها لشيكات إنهاء الحلقة، ولكن يجب أن لا تحاول إلغاء اختبار للماء وهو "==" ل ".end()".

نصائح أخرى

لم أتحقق من تنفيذ الخوارزمية الخاصة بك، سأشير فقط إلى أسئلتك الثلاثة:

  1. يشبه المزارعون إلى حد كبير المؤشرات لقيم الحاوية. إنه بالضبط مثل استخدام Size_t I ثم ++ I في حلقة. هل تشعر بأنها مشكلة لمقارنة الفصري [i] مع sarray [i]؟ ربما لا، لذلك كل شيء على ما يرام.
  2. ما أراك به في الكود الخاص بك هنا، هو أنك تقرأ فقط قيم * IT و * ITER، أنت لا تغيرها بالفعل، وبالتالي لن تتغير.
  3. نقاط النهاية () إلى مكان غير صالح. لا يشير إلى القيمة الأخيرة، ولكن "بعد ذلك". يبدو الأمر مثل "NULL" إذا كنت سوف، فهذا إذا كان (iTer == Sarray.end ()) صحيحا، فستحطمه إذا كنت ستكتب * ITER، لأنك لا تستطيع إلغاء اختبار للماء وهو يساوي الطرف ().

بعض النصائح العامة: تحتاج إلى التفكير في أسماء متغيرة. إن استدعاء ITERATON "IT" و "ITER" سوف يخلط بينك في مرحلة ما. في الواقع، إذا نظرت عن كثب، فإن لديها بالفعل. إذا كانت "Farray" و "Sarray" أسماء ذات مغزى، فماذا عن "FIEDER" و "HIDER".

أيضا، فكر من خلال ما يفعله فرز الدمج. هاتان كتلتين الماضيين موجودة فقط إلى "استنزاف" أيهما يمكن أن يترك بعض الأشياء. لذلك لا يحتاجون إلى أن يكونوا في الحلقة الأولى.

ربما أكتبها باسم (pseudocode):

while not (list1.empty and list2.empty):
    if list1.empty:
        result.push(list2.pop)
    else if list2.empty:
        result.push(list1.pop)
    else if list1.top > list2.top:
        result.push(list2.pop)
    else:
        result.push(list1.pop)

أو في البضائع الصدئة إلى حد ما C ++:

std::vector<int>::iterator fiter = farray.begin();
std::vector<int>::iterator siter = sarray.begin();

while (fiter != farray.end() || siter != sarray.end()) {
    if (fiter == farray.end())      final.push_back(*siter++);
    else if (siter == sarray.end()) final.push_back(*fiter++);
    else if (*fiter > *siter)       final.push_back(*siter++);
    else                            final.push_back(*siter++);
}

لديك بعض الأشياء للتفكير هنا.

أولا، إذا كنت دمج نطاقات، فستكون أفضل بكثير باستخدام STD :: دمج وظيفة بدلا أن تدحرج الخاصة بك.

يعد الرمز الخاص بك من الصعب قراءته لأنك تستخدم أنماط متفاوتة للمسافة البادئة وأين تقوم بإخراج الأقواس المجعد. اختيار النمط والتمسك بها.

يبدو أن الجزء الأول من حلقة الخاص بك هو تطبيق صحيح للدمج:

for (;it != farray.end() && iter != sarray.end();) {
    if (*it > *iter) {
        final.push_back(*it);
        it++;
    }    
    else
    {
        final.push_back(*iter);
        iter++;
    }

... وهذا يجب أن يكون كل ما تحتاجه للحصول على وظيفة القيام به.

الجزء الثاني من حلقة الخاص بك لديه مشاكل زوجين:

   for (;it != farray.end() && iter != sarray.end();) {
         :   :
            if (it == farray.end()) {
                for (int i = 0; iter < sarray.end(); i++) {
                    final.push_back(*iter);
                }
            }

            if (iter == sarray.end()) {
                for (int i = 0; it < farray.end(); i++) {
                    final.push_back(*iter);
                }
            }
        }

لشيء واحد، يتم كتابة الشرطية for () بحيث it و iter يجب ألا يشير إلى end() من جمع كل منها، وإلا ينتهي الحلقة. وبالتالي it لا يمكن أن تشير أبدا إلى sarray.end(), iter لا يمكن أن تشير أبدا إلى farray.end(), ، ولا if يمكن إطلاق البيان من أي وقت مضى. كلاهما كلا الرمز الميت (غير القابل للوصول).

ولكن حتى لو لم تكن رمزا ميتا، لديهم أخطاء. الشرطية في for(...) يكسر الحلقة عندما يشير المحامون إلى نهاية المجموعة، ولكن لا يتم نقل هذا المحفز أبدا، لذلك لديك حلقة لا حصر لها.

مرة أخرى كل من هذه for(...)S غير المرغوب فيه رمز ميت لأن المحامين لا يمكن أن يشيروا إلى نهاية المتجه.

تعليق واحد بسيط: لماذا لا تستخدم while (condition) بدلا من for(; !condition; ).

البناء الأخير غير قياسي ويصعب فهمه!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top