Pregunta

No set_intersection usado antes, pero creo que va a trabajar con los mapas. Escribí el siguiente código de ejemplo, pero no me da lo que cabe esperar:

#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;
}

Desde el par etiqueta (3) y (4) aparecen en ambos mapas, que estaba esperando que me gustaría obtener 2 elementos en la intersección, pero no, consigo:

intersection has 0 elements.

Estoy seguro de que esto es algo que ver con el comparador en el mapa / par, pero no puedo con ello.

¿Fue útil?

Solución

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 menos que esto es un error tipográfico, que se acaba de volver a insertar cosas en map1 en lugar de insertar en map2. He comprobado a cabo con el código corregido y emitida "Intersección tiene 2 elementos."

Otros consejos

Niki es ciertamente correcto acerca de su error tipográfico - map2 está vacía aquí! Sin embargo es necesario tener cuidado con algo más.

Digamos que su código era la siguiente:

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 ) );

Ahora, ¿qué pasaría? Que iba a encontrar que out sería vacío porque usos set_intersection std::less para comparar elementos, y los elementos de los mapas son pares - por lo tanto, (3 mn [3]) difiere de (3, MN [4]).

La otra forma en que podría hacerlo es mediante la escritura

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

Ahora, out contendrá dos elementos: (3, MN [3]) y (4, mn [4]), debido a que su teclas partido. Los elementos siempre se copian de la primera gama de iterador.

Tenga en cuenta que los mapas están siempre ordenados por el tipo map::value_compare que contienen. Si estás usando una función de comparación cobarde, set_intersection no funcionará sin el funtor comparación suministrado de forma explícita si los elementos del mapa no sucede estar en orden con respecto a std::less.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top