3

以前は 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) というラベルの付いたペアが両方のマップに表示されるため、交差点で 2 つの要素が得られると予想していましたが、そうではありません。

intersection has 0 elements.

これは、マップ/ペアのコンパレーターと関係があると確信していますが、それを理解することはできません.

4

2 に答える 2

6

Niki は確かにあなたのタイプミスについて正しいです --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あるため、空になることがわかります。したがって、(3, mn[3]) は (3, mn[4]) とは異なります。set_intersectionstd::less

これを行う別の方法は、次のように書くことです

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

キーが一致outするため、(3, mn[3]) と (4, mn[4]) の 2 つの要素が含まれます。要素は常に最初の反復子範囲からコピーされます。

マップは、含まれるタイプによって常にソートされることに注意してくださいmap::value_compare。ファンキーな比較関数を使用しているset_intersection場合、マップの要素が に対して順序付けされていない場合、明示的に指定された比較ファンクターがないと機能しませんstd::less

于 2010-04-14T01:09:45.880 に答える
5
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] ) );

これがタイプミスでない限り、map2 に挿入するのではなく、map1 に再挿入しているだけです。修正したコードでテストしたところ、「交差点には2つの要素があります」と出力されました。

于 2010-04-14T00:00:49.263 に答える