在地图上的键上用C ++设置交集

时间:2019-05-13 22:50:44

标签: c++ dictionary std set-intersection

我有两张地图

map<string, int> word_count1, word_count2;

我正在尝试查找这两个地图之间的已设置交点。在std :: algorithms中使用set_intersection方法。

map<string, int> intersection;
set_intersection(word_count1.begin(), word_count1.end(), 
                 word_count2.begin(), word_count2.end(), 
                 inserter(intersection, intersection.begin()), 
                  [](pair<string, int> p1, pair<string, int>p2){
                           return p1.first != p2.first;
                  });

我已经尝试过在没有比较功能的情况下使用word_count1.key_comp()和上述基于lambda的比较功能。

我知道

  1. 两个地图中都有数据。
  2. 交集不为空。

但是,当我检查相交图中的值时,我什么也没找到。

我也尝试了不使用插入器的情况,并且从函数调用中返回的返回值表明没有值!我在做什么错了?

2 个答案:

答案 0 :(得分:2)

您需要稍微修改lambda。比较操作是operator<,而不是operator==,因此您需要类似以下内容:

std::set_intersection
    (word_count1.begin(), word_count1.end(), 
     word_count2.begin(), word_count2.end(), 
     inserter (intersection, intersection.begin()),
     [](const std::pair<std::string, int> &p1, const std::pair<std::string, int> &p2)
         {return p1.first < p2.first;});

还要注意,最好将参数作为const ref传递给lambda,因为这样可以避免不必要的复制,对于C ++ 14和更高版本,可以将lambda简化为:

 [](const auto &p1, const auto &p2)
     {return p1.first < p2.first;});

Live demo

答案 1 :(得分:2)

对于std::set_intersection的比较运算符似乎有些误解。如果第一个元素小于第二个元素,则比较器函数(或lambda)必须返回true。因此,!===均未返回正确的(即预期的)结果。更改运算符即可使用:

std::set_intersection(word_count1.begin(), word_count1.end(),
             word_count2.begin(), word_count2.end(),
             inserter(intersection, intersection.begin()),
              [](std::pair<std::string, int> p1, std::pair<std::string, int>p2){
                       // Compare with less than operator here.
                       return p1.first < p2.first;
              });

一个完整的工作示例可能是:

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

int main(int argc, char** argv)
{
  std::map<std::string, int> word_count1 = {
    { "foo", 1 },
    { "bar", 3 },
    { "baz", 5 }
  };

  std::map<std::string, int> word_count2 = {
    { "foo", 4 },
    { "qux", 2 },
    { "baz", 5 },
    { "quux", 6 }
  };


  std::map<std::string, int> intersection;
  std::set_intersection(word_count1.begin(), word_count1.end(),
      word_count2.begin(), word_count2.end(),
      inserter(intersection, intersection.begin()),
      [](std::pair<std::string, int> p1, std::pair<std::string, int>p2){
          return p1.first < p2.first;
      }
  );

  for(const auto & elem: intersection)
  {
    std::cout << elem.first << " " << elem.second << "\n";
  }
}

在这种情况下的输出是:

baz 5
foo 1

(已在GCC 7.4.0中进行了测试。)