compare two multimaps c++

后端 未结 3 1843
盖世英雄少女心
盖世英雄少女心 2020-12-10 23:13

I have two multimaps.i would like to create a new multimap which has the common key-value pairs in the given those two multimaps:

for eg:

#include &l         


        
相关标签:
3条回答
  • 2020-12-10 23:22

    Use the std::set_intersection function template from <algorithm>

    std::multimap<T1, T2> newMap;
    std::set_intersection(map1.begin(), map1.end(), 
                          map2.begin(), map2.end(), 
                          std::inserter(newMap, newMap.begin());
    

    Edit Yeah, apparently this doesn't work for a multimap as it would for a map. I suggest the following:

    std::multimap<T1, T2> newMap;
    std::vector<std::multimap<T1, T2>::value_type> v1(map1.begin(), map1.end());
    std::sort(v1.begin(), v1.end());
    std::vector<std::multimap<T1, T2>::value_type> v2(map2.begin(), map2.end());
    std::sort(v2.begin(), v2.end());
    std::set_intersection(v1.begin(), v1.end(), 
                          v2.begin(), v2.end(), 
                          std::inserter(newMap, newMap.begin());
    
    0 讨论(0)
  • 2020-12-10 23:29

    As an alternative solution to Armen's (which is excellent), here's a way to copy and sort at the same time:

    typedef std::multimap<std::string, std::string> map_type;
    map_type m, n, result;
    
    m.insert(std::make_pair("1-2", "1-1"));
    // --------8<--------
    n.insert(std::make_pair("1-3", "21-2"));
    
    // --------8<--------    
    
    std::set<map_type::value_type> s1(m.begin(), m.end());
    std::set<map_type::value_type> s2(n.begin(), n.end());
    std::set_intersection(s1.begin(), s1.end(), 
                          s2.begin(), s2.end(), 
                          std::inserter(result, result.end()));
    

    Output:

    intersection
    ============
    1-2 1-1
    1-2 1-2
    1-3 2-1
    1-3 21-2
    

    To get the elements that are only in m:

    result.clear();
    std::set_difference(s1.begin(), s1.end(), 
                        s2.begin(), s2.end(), 
                        std::inserter(result, result.end()));
    

    And only in n:

    result.clear();
    std::set_difference(s2.begin(), s2.end(), 
                        s1.begin(), s1.end(), 
                        std::inserter(result, result.end()));
    

    See it run.

    Since you've copied m and n (into s1 and s2) at the time of doing the set_difference(), you could clear() these and insert into them instead of result.

    0 讨论(0)
  • 2020-12-10 23:29

    For fun, here's the direct algorithm, which moves common elements into a new multimap, changing the original maps. You will recognize the standard "set intersection" algorithm for sorted ranges on the outer loop (concerning first); and since we cannot assume anything about the mapped values, the inner loop (concerning second) is a linear search over the mapped values to find equals.

    template <typename T>
    T move_common(T & a, T & b)
    {
      typename T::const_iterator it1 = a.cbegin(), iend = a.cend(), jt1 = b.cbegin(), jend = b.cend();
    
      T result;
    
      while (it1 != iend && jt1 != jend)
      {
        if (it1->first < jt1->first)
        {
          ++it1;
        }
        else if (jt1->first < it1->first)
        {
          ++jt1;
        }
        else
        {
          typename T::const_iterator it2 = it1;
    
          while (it2 != iend && it2->first == it1->first)
          {
            typename T::const_iterator jt2 = jt1;
            while (jt2 != jend && jt2->first == jt1->first)
            {
              if (jt2->second == it2->second)
              {
                result.insert(*it2);
                if (it2 == it1) { a.erase(it1++); it2 = it1; } else { a.erase(it2++); }
                if (jt2 == jt1) { b.erase(jt1++); } else { b.erase(jt2); }
                break;
              }
              else
              {
                ++jt2;
                if (jt2 == jend || jt2->first != jt1->first) { ++it2; break; }
              }
            }
          }
          it1 = it2;
        }
      }
      return result;
    }
    

    Result:

    common  = [(1-2, 1-1), (1-2, 1-2), (1-3, 2-1), (1-3, 21-2)]
    n after = [(1-2, 1-3), (1-2, 1-4), (1-3, 21-1)]
    m after = [(1-2, 1-5), (1-2, 1-7), (1-3, 21-4)]
    
    0 讨论(0)
提交回复
热议问题