在C ++ stl </std :: pair>中std :: list <std :: pair>和std :: map之间的区别

时间:2010-08-02 16:21:03

标签: c++ stl

请告诉我std :: list&lt; std :: pair&gt;之间的区别和std :: map。我也可以在列表中使用find方法吗?

谢谢。

- 澄清

编辑问题要更清楚。

7 个答案:

答案 0 :(得分:105)

std::map<X, Y>

  • 是一个关于键的有序结构(也就是说,当你遍历它时,键会一直增加)。
  • 仅支持唯一键(X s)
  • 提供快速find()方法(O(log n)),按键找到键值对
  • 提供了一个索引运算符map[key],它也很快

std::list<std::pair<X, Y> >

  • 是配对XY的简单序列。它们保持在您输入的顺序中。
  • 可以容纳任意数量的重复
  • list中查找特定密钥为O(N)(无特殊方法)
  • 提供splice方法。

答案 1 :(得分:20)

std::pair

std::pair是一个模板化的元组结构,仅限于2个项目,分别称为第一个和第二个:

std::pair<int, std::string> myPair ;
myPair.first = 42 ;
myPair.second = "Hello World" ;

std::pair被STL(和其他代码)用作“通用容器”,可以同时聚合两个值,而无需重新定义另一个struct

std::map

std::map是一个模板化的关联容器,它将键和值关联在一起。最简单(但效率不高)的例子是:

std::map<int, std::string> myMap ;
myMap[42] = "Fourty Two" ;
myMap[111] = "Hello World" ;
// ...
std::string strText ;  // strText is ""
strText = myMap[111] ; // strText is now "Hello World"
strText = myMap[42] ;  // strText is now "Fourty Two"
strText = myMap[23] ;  // strText is now "" (and myMap has
                       // a new value "" for key 23)

std::pairstd::map

注意:这是原始未经编辑的问题的答案。

std::map函数需要同时将迭代器返回到键和值以保持高效...所以显而易见的解决方案是将迭代器返回到对:

std::map<int, std::string> myMap ;
myMap[42] = "Fourty Two" ;
myMap[111] = "Hello World" ;

myMap.insert(std::make_pair(23, "Bye")) ;

std::map<int, std::string>::iterator it = myMap.find(42) ;
std::pair<int, std::string> keyvalue = *it ;    // We assume 42 does
                                                // exist in the map
int key = keyvalue.first ;
int value = keyvalue.second ;

std::list<std::pair<A,B> >std::map<A,B>

注意:在问题编辑后编辑。

因此,乍一看,对的映射和对的列表看起来是一样的。但事实并非如此:

地图本身是由提供的仿函数排序的,而列表会将[A,B]对保持在你放置它们的位置。这使得映射的插入O(log n),而列表中的原始插入是一个恒定的复杂性(搜索插入位置是另一个问题)。

您可以使用对列表稍微模拟地图的行为,但请注意,地图通常实现为项目树,而列表是项目的链式列表。因此,像二分法这样的算法在地图中比在列表中工作得快得多。

因此,在地图中查找项目是O(log n),而在无序列表中,它是O(n)。如果列表是有序的,并且您想要使用二分法,则无法获得预期的性能提升,因为遍历项目列表仍然是逐项完成的。

在一年前我工作的一个项目中,我们用一组相同的有序项替换了一个有序项目列表,它提升了性能。该集合具有与地图相同的内部树结构,我想同样的提升将在这里适用

答案 2 :(得分:3)

(澄清后编辑)

std::map针对快速搜索进行了优化。它有自己的find方法,它使用其内部结构来提供良好的性能。通常,它只会检查log(N)个键,其中N是地图中的项目数。

std::list<std::pair>是一个简单的链表,因此只支持逐个元素遍历。您可以使用单独的std::find算法,或std::find_if使用自定义谓词,该谓词仅检查first成员以更好地匹配std::map::find的语义,但那会很慢。实际上,对于任何失败的搜索,它必须查看列表中的每个对,并且对于任何成功的搜索,它将平均看一半。

答案 3 :(得分:2)

std:pair正好包含两个对象。 std:map拥有一组配对对象。

你不能在对上使用find(),因为没有什么可以找到的。您想要的对象是pair.Firstpair.Second

更新: 假设您的意思是map<>list<pair<> >之间的区别:应该实现Map以便在key成员上快速查找。 list只有一个简单的线性列表。查找列表中的项目需要遍历整个列表。但是,std :: find()将适用于两者。

答案 4 :(得分:1)

STL贴图是关联数组,通常在内部实​​现为散列图。如果你想在STL地图上进行迭代,它将返回一个STL对。

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
        map<string, int> myMap;
        myMap["myKey"] = 1337;

        map<string, int>::iterator myIterator = myMap.begin();

        pair<string, int> myPair = *myIterator;

        cout<<"the key \""<<myPair.first<<"\" maps to the value of "<<myPair.second<<endl;
        cout<<"the key \"myKey"\" maps to the value of "<<myMap["myKey"]<<endl;
        return 0;
}

我建议谷歌搜索和阅读完整的STL API参考,因为STL(除了在矢量中存储布尔值和其他奇怪的东西)实现了许多数据结构功能,你想要在任何程序中使用而不需要重新发明轮子。

答案 5 :(得分:0)

std :: pair仅用于将2个对象组合在一起(例如,“页面上的坐标”由X和Y组成)。

std :: map是从一组对象到另一组对象的映射。

尝试在一对上使用find方法是没有意义的,因为在一个你知道顺序的两个东西的列表中找到一些东西是有意义的,即使这个find方法存在于一个对类中它也是如此没有。

但是,如果这是你想要的,你可以使用std :: pair作为地图值。

答案 6 :(得分:0)

Map可以在O(log n)范围内提供更好的搜索时间, whilw列表可以有O(n)的搜索时间。