سؤال

لا تستخدم set_intersection من قبل ، لكنني أعتقد أنها ستعمل مع الخرائط. كتبت رمز المثال التالي ولكن لا يعطيني ما أتوقعه:

#include <map>
#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

struct Money
{
    double amount;
    string currency;

    bool operator< ( const Money& rhs ) const
    {
        if ( amount != rhs.amount )
            return ( amount < rhs.amount );
        return ( currency < rhs.currency );
    }
};

int main( int argc, char* argv[] )
{
    Money mn[] =
    {
        { 2.32,  "USD" },
        { 2.76,  "USD" },
        { 4.30,  "GBP" },
        { 1.21,  "GBP" },

        { 1.37,  "GBP" },
        { 6.74,  "GBP" },
        { 2.55,  "EUR" }
    };

    typedef pair< int, Money > MoneyPair;
    typedef map< int, Money > MoneyMap;

    MoneyMap map1;
    map1.insert( MoneyPair( 1, mn[0] ) );
    map1.insert( MoneyPair( 2, mn[1] ) );
    map1.insert( MoneyPair( 3, mn[2] ) );  // (3)
    map1.insert( MoneyPair( 4, mn[3] ) );  // (4)

    MoneyMap map2;
    map2.insert( MoneyPair( 3, mn[2] ) );  // (3)
    map2.insert( MoneyPair( 4, mn[3] ) );  // (4)
    map2.insert( MoneyPair( 5, mn[4] ) );
    map2.insert( MoneyPair( 6, mn[5] ) );
    map2.insert( MoneyPair( 7, mn[6] ) );

    MoneyMap out;
    MoneyMap::iterator out_itr( out.begin() );
    set_intersection( map1.begin(), map1.end(), map2.begin(), map2.end(), inserter( out, out_itr ) );

    cout << "intersection has " << out.size() << " elements." << endl;
    return 0;
}

بما أن الزوج المسمى (3) و (4) يظهران في كلتا الخريطتين ، كنت أتوقع أن أحصل على عنصرين في التقاطع ، لكن لا ، أحصل على:

intersection has 0 elements.

أنا متأكد من أن هذا شيء يتعلق بالمقارن على الخريطة / الزوج ولكن لا يمكنني اكتشافه.

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

المحلول

MoneyMap map2;
map1.insert( MoneyPair( 3, mn[3] ) );  // (3)
map1.insert( MoneyPair( 4, mn[4] ) );  // (4)
map1.insert( MoneyPair( 5, mn[5] ) );
map1.insert( MoneyPair( 6, mn[6] ) );
map1.insert( MoneyPair( 7, mn[7] ) );

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

نصائح أخرى

نيكي بالتأكيد على صواب حول الخطأ المطبعي الخاص بك - map2 فارغ هنا! ومع ذلك ، عليك أن تكون حذراً بشأن شيء آخر.

دعنا نقول أن الكود الخاص بك يشبه هذا:

MoneyMap map1;
map1.insert( MoneyPair( 1, mn[1] ) );
map1.insert( MoneyPair( 2, mn[2] ) );
map1.insert( MoneyPair( 3, mn[3] ) );  // (3)
map1.insert( MoneyPair( 4, mn[4] ) );  // (4)

MoneyMap map2;
map2.insert( MoneyPair( 3, mn[4] ) );  // (3)
map2.insert( MoneyPair( 4, mn[3] ) );  // (4)
map2.insert( MoneyPair( 5, mn[6] ) );
map2.insert( MoneyPair( 6, mn[5] ) );
map2.insert( MoneyPair( 7, mn[1] ) );

MoneyMap out;
MoneyMap::iterator out_itr( out.begin() );
set_intersection(map1.begin(), map1.end(), 
                 map2.begin(), map2.end(), 
                 inserter( out, out_itr ) );

الآن ، ماذا سيحدث؟ ستجد ذلك out سيكون فارغا لأن set_intersection الاستخدامات std::less لمقارنة العناصر ، وعناصر خرائطك هي أزواج - وبالتالي (3 ، MN [3]) تختلف عن (3 ، Mn [4]).

الطريقة الأخرى التي يمكنك القيام بذلك هي عن طريق الكتابة

set_intersection(map1.begin(), map1.end(), 
                 map2.begin(), map2.end(), 
                 inserter( out, out_itr ), map1.value_comp() );

الآن، out سوف يحتوي على عنصرين: (3 ، MN [3]) و (4 ، Mn [4]) ، لأنهم مفاتيح تطابق. يتم نسخ العناصر دائمًا من نطاق التكرار الأول.

لاحظ أن الخرائط يتم فرزها دائمًا حسب النوع map::value_compare انهم يحتوون. إذا كنت تستخدم وظيفة مقارنة غير تقليدي ، set_intersection لن يعمل بدون المقارنة المقارنة الموفرة بشكل صريح إذا لم تكن عناصر الخريطة في حالة جيدة std::less.

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