Map comparison between key value pairs

Discussion in 'C++' started by Evyn, Jan 22, 2007.

  1. Evyn

    Evyn Guest

    Hi,

    How do I compare 2 maps for identical keys, and if they have identical
    keys, check if they have identical values? In either case I want to
    copy ONLY that key value pair to one of two different maps.

    I know how to copy the entire map to another:
    // Copy fset1 to fset3
    std::copy(fset1.begin(),fset1.end(),std::inserter(fset3,
    fset3.begin()));

    And I can for example iterate through the entire map, but the key pair
    comparison is beyond me at this point.

    // Print test
    for (std::map<double,double>::const_iterator iter = fset3.begin();
    iter != fset3.end(); ++iter )
    {
    std::cout << iter->first << " , " << iter->second << "\n";
    }


    Thank you for your time
    Evyn
    Evyn, Jan 22, 2007
    #1
    1. Advertising

  2. Evyn

    Kai-Uwe Bux Guest

    Evyn wrote:

    > Hi,
    >
    > How do I compare 2 maps for identical keys, and if they have identical
    > keys, check if they have identical values? In either case I want to
    > copy ONLY that key value pair to one of two different maps.
    >
    > I know how to copy the entire map to another:
    > // Copy fset1 to fset3
    > std::copy(fset1.begin(),fset1.end(),std::inserter(fset3,
    > fset3.begin()));
    >
    > And I can for example iterate through the entire map, but the key pair
    > comparison is beyond me at this point.
    >
    > // Print test
    > for (std::map<double,double>::const_iterator iter = fset3.begin();
    > iter != fset3.end(); ++iter )
    > {
    > std::cout << iter->first << " , " << iter->second << "\n";
    > }


    Ponder:

    #include <map>
    #include <algorithm>
    #include <iterator>
    #include <iostream>

    int main ( void ) {
    std::map< int, int > a;
    std::map< int, int > b;
    b[2] = 1;
    b[4] = 2;
    b[3] = 1;
    a[3] = 0;
    a[5] = 2;
    a[4] = 5;
    a[2] = 3;

    typedef std::map<int,int>::const_iterator const_map_iter;

    const_map_iter a_iter = a.begin();
    const_map_iter b_iter = b.begin();
    while ( a_iter != a.end() && b_iter != b.end() ) {
    if ( a_iter->first < b_iter->first ) {
    ++ a_iter;
    continue;
    }
    if ( b_iter->first < a_iter->first ) {
    ++ b_iter;
    continue;
    }
    // if we get here, keys match:
    std::cout << "key : "
    << a_iter->first
    << " matches "
    << b_iter->first
    << ". value in a : "
    << a_iter->second
    << ". value in b : "
    << b_iter->second
    << '\n';
    // do not forget to increment in this case:
    ++ a_iter;
    ++ b_iter;
    }
    }


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jan 22, 2007
    #2
    1. Advertising

  3. On Jan 22, 12:34 pm, "Evyn" <> wrote:
    > Hi,
    >
    > How do I compare 2 maps for identical keys, and if they have identical
    > keys, check if they have identical values? In either case I want to
    > copy ONLY that key value pair to one of two different maps.
    >
    > I know how to copy the entire map to another:
    > // Copy fset1 to fset3
    > std::copy(fset1.begin(),fset1.end(),std::inserter(fset3,
    > fset3.begin()));
    >
    > And I can for example iterate through the entire map, but the key pair
    > comparison is beyond me at this point.


    You need to understand that an iterator to a map points to a std::pair,
    so what's stored in the map is acctually std::pair-objects which
    contains both the key and the value. The nice thing about this is that
    you can compare std::pairs to each other, if you have two pairs, x and
    y then
    x == y
    is the same thing as
    x.first == y.first && x.second == y.second
    which means that comparing the pairs in the tree compares both the keys
    and the values.

    I don't quite understand what you mean whit copying only to one of the
    maps. Do you mean that you want to extract the key/value pairs that are
    unique in the two maps? You might want to look at the
    set_symmetric_difference or set_difference algorithms.

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jan 22, 2007
    #3
  4. Evyn

    Daniel T. Guest

    "Evyn" <> wrote:

    > How do I compare 2 maps for identical keys, and if they have identical
    > keys, check if they have identical values? In either case I want to
    > copy ONLY that key value pair to one of two different maps.


    So after the operation, the map should be identical, or do you want the
    first map to have all the key/values it had plus any key/values that are
    in the second map that the first didn't have?

    > I know how to copy the entire map to another:
    > // Copy fset1 to fset3
    > std::copy(fset1.begin(),fset1.end(),std::inserter(fset3,
    > fset3.begin()));


    Is the end product of this operation what you want?
    Daniel T., Jan 22, 2007
    #4
  5. Evyn

    Evyn Guest

    Essentially, I want to compare the key value pair in 2 maps and copy
    all unique key value pairs to a third map. In the case where the keys
    are not unique, I still want to copy the key value pair to the third
    map, but where the value is higher...

    Thanks for your time again
    Evyn, Jan 23, 2007
    #5
  6. Evyn

    Ondra Holub Guest

    Evyn napsal:
    > Hi,
    >
    > How do I compare 2 maps for identical keys, and if they have identical
    > keys, check if they have identical values? In either case I want to
    > copy ONLY that key value pair to one of two different maps.
    >
    > I know how to copy the entire map to another:
    > // Copy fset1 to fset3
    > std::copy(fset1.begin(),fset1.end(),std::inserter(fset3,
    > fset3.begin()));
    >
    > And I can for example iterate through the entire map, but the key pair
    > comparison is beyond me at this point.
    >
    > // Print test
    > for (std::map<double,double>::const_iterator iter = fset3.begin();
    > iter != fset3.end(); ++iter )
    > {
    > std::cout << iter->first << " , " << iter->second << "\n";
    > }
    >
    >
    > Thank you for your time
    > Evyn


    See function Join:

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

    typedef
    std::map<std::string, int> M;

    void Dump(const std::string& prompt, const M& m)
    {
    std::cout << prompt << ":\n";
    for (M::const_iterator it = m.begin(); it != m.end(); ++it)
    {
    std::cout << '[' << it->first << "] = " << it->second << '\n';
    }
    std::cout << '\n';
    }

    template<typename KEY, typename DATA>
    void Join(
    std::map<KEY, DATA>& result,
    const std::map<KEY, DATA>& m1,
    const std::map<KEY, DATA>& m2
    )
    {
    result.insert(m1.begin(), m1.end());
    for (typename std::map<KEY, DATA>::const_iterator it = m2.begin();
    it != m2.end();
    ++it
    )
    {
    typename std::map<KEY, DATA>::iterator fi =
    result.find(it->first);
    if (fi == result.end())
    result.insert(*it);
    else
    if (fi->second < it->second)
    fi->second = it->second;
    }
    }

    int main()
    {
    M m1;
    M m2;

    m1["a"] = 1;
    m1["b"] = 2;
    m1["c"] = 33;

    m2["b"] = 22;
    m2["c"] = 3;
    m2["d"] = 44;

    Dump("m1", m1);
    Dump("m2", m2);

    M result;
    Join(result, m1, m2);

    Dump("result", result);
    };
    Ondra Holub, Jan 23, 2007
    #6
  7. On Jan 23, 1:32 pm, "Evyn" <> wrote:
    > Essentially, I want to compare the key value pair in 2 maps and copy
    > all unique key value pairs to a third map. In the case where the keys
    > are not unique, I still want to copy the key value pair to the third
    > map, but where the value is higher...


    std::set_union is what you want, together with an insert_iterator.

    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <map>

    bool cmp(
    const std::pair<int, int>& p1,
    const std::pair<int, int>& p2
    )
    {
    if (p1.first < p2.first)
    return true;
    if (p1.first == p2.first)
    return p1.second > p2.second;
    return false;
    }

    int main()
    {
    std::map<int, int> m1;
    std::map<int, int> m2;
    std::map<int, int> mR;

    // Set values
    m1[1] = 1; m1[2] = 2; m1[3] = 3;
    m1[4] = 4; m1[5] = 5; m1[6] = 6;

    m2[1] = 3; m2[2] = 2; m2[4] = 5;
    m2[5] = 3; m2[8] = 1; m2[9] = 4;

    // Get insert iterator and run set_union
    std::insert_iterator<std::map<int, int> > ins(mR, mR.begin());
    std::set_union(m1.begin(), m1.end(), m2.begin(), m2.end(), ins, cmp);

    // Print
    for (std::map<int, int>::iterator i = mR.begin(); i != mR.end(); ++i)
    std::cout << i->first << " " << i->second << "\n";

    return 0;
    }

    Hope the code survives the line-breaks.

    --
    Erik Wikström
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jan 23, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patrick Guio
    Replies:
    6
    Views:
    3,181
    chris
    Oct 20, 2004
  2. Florian Lindner

    key - key pairs

    Florian Lindner, Jun 23, 2005, in forum: Python
    Replies:
    8
    Views:
    543
    Paul McGuire
    Jun 24, 2005
  3. Markus Dehmann

    key-value pairs: key consists of 3 ints

    Markus Dehmann, Jan 15, 2006, in forum: C++
    Replies:
    13
    Views:
    627
    Richard Herring
    Jan 23, 2006
  4. Replies:
    2
    Views:
    330
    Frank Birbacher
    May 23, 2008
  5. Antonio Quinonez
    Replies:
    2
    Views:
    157
    Antonio Quinonez
    Aug 14, 2003
Loading...

Share This Page