Mit Hilfe einer Karte mit set_intersection
-
26-09-2019 - |
Frage
Nicht gebrauchte set_intersection vor, aber ich glaube, es wird mit Karten arbeiten. Ich schrieb den folgenden Beispielcode, aber es gibt mir nicht, was ich erwarten würde:
#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;
}
Da das Paar markiert (3) und (4) erscheinen in den beiden Karten, erwarte ich, dass ich zwei Elemente in der Kreuzung bekommen würde, aber nein, ich:
intersection has 0 elements.
Ich bin sicher, dass dies etwas ist, mit dem Vergleichers auf der Karte / pair zu tun, aber kann es nicht herausgefunden.
Lösung
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] ) );
Es sei denn, dies ein Tippfehler ist, werden Sie wieder einsetzen nur Sachen in map1 statt Einfügen in map2. I getestet es mit dem korrigierten Code und es ausgegeben „Überschneidung 2 Elemente aufweist.“
Andere Tipps
Niki ist sicher richtig über Ihre Tippfehler - map2
ist hier leer! Allerdings müssen Sie über etwas anderes, vorsichtig sein.
Angenommen, Ihr Code wie folgt aussieht:
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 ) );
Nun, was würde passieren? Sie würden, dass out
wäre leer finden, weil set_intersection
Anwendungen std::less
Elemente zu vergleichen, und die Elemente Ihrer Karten sind Paare - also (3, mn [3]) unterscheidet sich von (3, mn [4]).
Der andere Weg, dies tun könnte durch Schreiben ist
set_intersection(map1.begin(), map1.end(),
map2.begin(), map2.end(),
inserter( out, out_itr ), map1.value_comp() );
Nun wird out
zwei Elemente enthalten: (3, mn [3]) und (4, mn [4]), weil ihr Tasten Spiel. Die Elemente werden immer von dem ersten Iterator Bereich kopiert.
Beachten Sie, dass die Karten immer vom map::value_compare
Typ sortiert sind sie enthalten. Wenn Sie eine funky Vergleichsfunktion verwenden, set_intersection
wird nicht funktionieren, ohne den Vergleich Funktor geliefert ausdrücklich, wenn die Elemente der Karte nicht in Bezug auf std::less
, um passieren zu sein.