Utilizzando una mappa con set_intersection
-
26-09-2019 - |
Domanda
Non set_intersection usato prima, ma credo che possa funzionare con le mappe. Ho scritto il seguente codice di esempio, ma non mi dà quello che mi aspetto:
#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;
}
Dal momento che la coppia etichettato (3) e (4) comparire in entrambe le mappe, mi aspettavo che mi piacerebbe avere 2 elementi in punti di incontro, ma no, ottengo:
intersection has 0 elements.
Sono sicuro che questo è qualcosa a che fare con la comparitor sulla mappa / pair, ma non riesco a capirlo.
Soluzione
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] ) );
A meno che non si tratta di un errore di battitura, si sono solo reinserimento roba nel map1 invece di inserire in MAP2. Ho testato con il codice corretto ed in uscita "Intersezione ha 2 elementi."
Altri suggerimenti
Niki è certamente corretto sulla tua errore di battitura - map2
è svuotare qui! Tuttavia è necessario essere attenti a qualcosa d'altro.
Diciamo che il codice si presentava così:
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 ) );
Ora, che cosa accadrebbe? Che si può trovare che out
sarebbe vuoto perchè usi set_intersection
std::less
per confrontare gli elementi, e gli elementi delle mappe sono coppie - così (3, mn [3]) differisce da (3, mn [4]).
L'altro modo si potrebbe fare questo è scritto
set_intersection(map1.begin(), map1.end(),
map2.begin(), map2.end(),
inserter( out, out_itr ), map1.value_comp() );
Ora, out
conterrà due elementi: (3, mn [3]) e (4, mn [4]), perché la loro i tasti partita. Gli elementi sono sempre copiati dalla prima gamma iteratore.
Si noti che le mappe sono sempre ordinati in base al tipo di map::value_compare
che contengono. Se stai usando una funzione di confronto funky, set_intersection
non funzionerà senza il funtore confronto esplicitamente fornito se gli elementi della mappa non capita di essere in ordine rispetto a std::less
.