【问题标题】:compare two multimaps c++比较两个多图c ++
【发布时间】:2012-01-23 11:51:30
【问题描述】:

我有两个多图。我想创建一个新的多图,它在给定的这两个多图中具有公共键值对:

例如:

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main ()
{


multimap<std::string, std::string> m;
multimap<std::string, std::string> n;


m.insert(multimap<string,string>::value_type("1-2","1-1"));
m.insert(multimap<string,string>::value_type("1-2","1-2"));
m.insert(multimap<string,string>::value_type("1-2","1-3"));
m.insert(multimap<string,string>::value_type("1-2","1-4"));
m.insert(multimap<string,string>::value_type("1-3","2-1"));
m.insert(multimap<string,string>::value_type("1-3","21-1"));
m.insert(multimap<string,string>::value_type("1-3","21-2"));

n.insert(multimap<string,string>::value_type("1-2","1-1"));
n.insert(multimap<string,string>::value_type("1-2","1-2"));
n.insert(multimap<string,string>::value_type("1-2","1-5"));
n.insert(multimap<string,string>::value_type("1-2","1-7"));
n.insert(multimap<string,string>::value_type("1-3","2-1"));
n.insert(multimap<string,string>::value_type("1-3","21-4"));
n.insert(multimap<string,string>::value_type("1-3","21-2"));

cout<<"multimap of m"<<endl;
cout<<"--------------"<<endl;
for(multimap<string,string>::iterator i=m.begin();i!=m.end();i++)
cout <<i->first<<" "<<i->second<<endl;
cout<<"multimap of n"<<endl;
cout<<"--------------"<<endl;
for(multimap<string,string>::iterator i=n.begin();i!=n.end();i++)
cout <<i->first<<" "<<i->second<<endl;

}

这会导致:

multimap of m
--------------
1-2 1-1
1-2 1-2
1-2 1-3
1-2 1-4
1-3 2-1
1-3 21-1
1-3 21-2
multimap of n
--------------
1-2 1-1
1-2 1-2
1-2 1-5
1-2 1-7
1-3 2-1
1-3 21-4
1-3 21-2

我想创建一个新的多图:它具有以下元素:

1-2 1-1
1-2 1-2
1-3 2-1
1-3 21-2

编辑:

还有一种方法可以让我从两个地图中删除公共元素(对)。

【问题讨论】:

  • 我发布了一个直接算法,该算法适用于多图,也可以进行删除。

标签: c++ multimap


【解决方案1】:

使用来自&lt;algorithm&gt;std::set_intersection 函数模板

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

编辑 是的,显然这不适用于多地图,因为它适用于地图。我建议如下:

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

【讨论】:

  • 我运行了这个(使用 VS2010 构建),但它没有包含 1-3 21-2。如果我将 1-3 21-41-3 21-2 的插入交换到 n 中,那么它会产生正确的结果。
  • 我认为 set_intersection 需要在 stl 传递给它之前对其进行排序。
  • @RahulDravid,对于multimap,声明如下:“其键比较等效的键值对的顺序是插入顺序,不会改变。”
  • 是的,这意味着 set_intersection 在这种情况下不起作用!!因为我可以在值中包含未排序的数据
  • 是的......你是对的......但我有点担心 sort.nyways 我会尝试它。还有一种方法可以删除两者的共同元素地图?
【解决方案2】:

作为Armen's (which is excellent) 的替代解决方案,这是一种同时复制和排序的方法:

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

输出:

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

获取仅在m中的元素:

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

并且仅在n:

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

See it run.

由于您在执行set_difference() 时已复制mn(到s1s2),因此您可以将clear() 插入其中而不是result .

【讨论】:

  • +1:没想到套装。虽然老实说,我真的不知道一种方式或另一种方式是否会更快。让 OP 试一试
【解决方案3】:

为了好玩,这里是直接算法,它将公共元素移动到一个新的多地图中,改变了原始地图。您将认识到外部循环上排序范围的标准“设置交集”算法(关于first);由于我们无法对映射值进行任何假设,因此内部循环(关于 second)是对映射值的线性搜索以找到等于。

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

结果:

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

【讨论】:

    猜你喜欢
    • 2010-12-26
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多