如何了解两个`std :: multimap`内容是否相同?

时间:2018-12-11 20:37:11

标签: c++ stl multimap

我必须承认我从未对标准库进行过适当的研究,但这让我感到惊讶

#include <iostream>
#include <map>

int main (int argc, char ** argv)
{
    std::multimap<int, int> mm1;
    mm1.insert( std::pair<int, int>(0, 0) );
    mm1.insert( std::pair<int, int>(0, 1) );

    std::multimap<int, int> mm2;
    mm2.insert( std::pair<int, int>(0, 1) );
    mm2.insert( std::pair<int, int>(0, 0) );

    std::cout << "The maps are "
          << ( (mm1 == mm2) ? "equal" : "not equal" )
          << std::endl;
}

尝试一下,我们得到...

$ g++ --std=c++11 -o multimaporder multimaporder.cc
$ ./multimaporder 
The maps are not equal

因此,将事物放入地图的顺序很重要。那不是我对关联容器的最初期望,但是很好。

使用随机访问容器,我的下一个计划通常是对它们进行排序,然后进行比较...但是添加

#include <algorithm>
//...
    std::sort( mm1.begin(), mm1.end() );
    std::sort( mm2.begin(), mm2.end() );

    std::cout << "The *sorted* maps are "
              << ( (mm1 == mm2) ? "equal" : "not equal" )
              << std::endl;

仅仅因为没有找到一组可接受的迭代器来提交给sort而导致的公正结果。

那么找出两个multimap是否具有相同内容的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

  

因此,将事物放入地图的顺序很重要。

不,对于地图来说并不重要,但是您使用的是multimap,这是另一种野兽。如std::multimap::insert()

的文档所述
  

1-2)插入值。 如果容器包含具有等效键的元素,则在该范围的上限处插入。(自C ++ 11起)。重载(2)等效于emplace(std :: forward

(value)),并且仅在std :: is_constructible :: value == true时才参与重载解析。

重点是我的。可能的解决方案:

  • 通过向std::multimap提供适当的提示,将值插入std::multimap::insert中以在两个容器中保持相同的顺序(例如,已排序)。
  • 使用所有对都进行了完全排序的容器,例如std::set<std::pair<int,int>>,您应该了解行为上的差异
  • 使用特殊的比较器,它将以某种方式意识到不同顺序的值是否相等

请注意,您无法在std::multimap中求助于将其迭代器传递给std::sort的元素,这会破坏容器不变性。

答案 1 :(得分:1)

每个[associative.reqmts]/4 std::multimap要求保持等效键的插入顺序,因此,只有两个容器具有相同顺序的相同值时,它们才会比较相等。

如果您不关心顺序,则可以使用std::unordered_multimap,它不关心顺序,只要它们具有相同的值,它们就会相互比较

int main (int argc, char ** argv)
{
    std::unordered_multimap<int, int> mm1;
    mm1.insert( std::pair<int, int>(0, 0) );
    mm1.insert( std::pair<int, int>(0, 1) );

    std::unordered_multimap<int, int> mm2;
    mm2.insert( std::pair<int, int>(0, 1) );
    mm2.insert( std::pair<int, int>(0, 0) );

    std::cout << "The maps are "
          << ( (mm1 == mm2) ? "equal" : "not equal" )
          << std::endl;
}

输出

The maps are equal

答案 2 :(得分:1)

在这种情况下,您需要比较以下集合

bool comp ()
{
    using Map = std::multimap<int, int>;
    Map mm1;
    mm1.insert( std::pair<int, int>(0, 0) );
    mm1.insert( std::pair<int, int>(0, 1) );

    Map mm2;
    mm2.insert( std::pair<int, int>(0, 1) );
    mm2.insert( std::pair<int, int>(0, 0) );


    return std::set<Map::value_type>(mm1.begin(), mm1.end()) == std::set<Map::value_type>(mm2.begin(), mm2.end());
}