简体   繁体   English

std::list 和有什么区别<std::pair>和 C++ STL 中的 std::map ?

[英]What is the difference between std::list<std::pair> and std::map in C++ STL?

What is the difference between std::list<std::pair> and std::map ? std::list<std::pair>std::map什么区别? Is there a find method for the list, too?列表也有find方法吗?

std::map<X, Y> : std::map<X, Y>

  • is an ordered structure with respect to keys (that is, when you iterate over it, keys will be always increasing).是关于键的有序结构(也就是说,当您对其进行迭代时,键将始终增加)。
  • supports unique keys ( X s) only仅支持唯一键 ( X s)
  • offers fast find() method ( O(log n) ) which finds the Key-Value pair by Key提供快速find()方法( O(log n) ),它通过 Key 找到 Key-Value 对
  • offers an indexing operator map[key] , which is also fast提供索引运算符map[key] ,它也很快

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

  • is a simple sequence of paired X s and Y s.是成对的X s 和Y s 的简单序列。 They remain in the order you put it in.它们保留在您放入的顺序中。
  • can hold any number of duplicates可以容纳任意数量的重复项
  • finding a particular key in a list is O(N) (no special method)list查找特定键是O(N) (没有特殊方法)
  • offers the splice method.提供splice方法。

std::pair

std::pair is a templated tuple-structure limited to 2 items, called first and second: std::pair是一个模板化的元组结构,仅限于 2 个项目,称为第一和第二:

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

std::pair is used as a "generic container" by the STL (and other code) to aggregate two values at the same time without having to redefine yet another struct . std::pair被 STL(和其他代码)用作“通用容器”以同时聚合两个值,而无需重新定义另一个struct

std::map

std::map is an templated associative container, associating keys and values together. std::map是一个模板化的关联容器,将键和值关联在一起。 The easiest (but not more efficient) example is :最简单(但不是更有效)的例子是:

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::pair and std::map std::pairstd::map

Note: This was the answer to the original, unedited question.注意:这是原始未经编辑的问题的答案。

The std::map functions needs to return iterators to the keys and values at the same time to remain efficient... So the obvious solution is to return iterators to pairs: 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> > and std::map<A,B> std::list<std::pair<A,B> >std::map<A,B>

Note: Edited after edition of the question.注意:在问题版本后编辑。

Thus, at first glance, a map of pairs and a list of pairs would seem the same.因此,乍一看,对的映射和对的列表似乎相同。 But this is not the case:但这种情况并非如此:

The map is inherently ordered by the functor provided, whereas the list will keep the pairs of [A,B] right where you put them.映射本质上是由提供的函子排序的,而列表会将 [A,B] 对保持在您放置它们的位置。 This makes insertion O(log n) for the map, whereas raw insertion inside a list is a constant complexity (searching where to insert it is another problem).这使得映射的插入为 O(log n),而列表中的原始插入是一个恒定的复杂性(搜索在哪里插入它是另一个问题)。

You can simulate somewhat the behavior of a map using a list of pairs, but note that the map is usually implemented as a tree of items, whereas the list is a chained list of items.您可以使用成对列表在一定程度上模拟映射的行为,但请注意,映射通常实现为项目树,而列表是项目的链式列表。 Thus, algorithm like dichotomy will work a lot faster in a map than in a list.因此,像二分法这样的算法在地图中的工作速度比在列表中快得多。

Thus, finding an item in a map is O(log n), whereas in an unordered list, it is O(n).因此,在映射中查找项目的复杂度为 O(log n),而在无序列表中则为 O(n)。 And if the list is ordered, and you want to use dichotomy, you won't get the expected performance boost, as the traversal the list of items is done item by item anyway.如果列表是有序的,并且您想使用二分法,则不会获得预期的性能提升,因为无论如何遍历项目列表都是逐项完成的。

( In a project I worked on one year ago, we replaced a list of ordered items by a set of the same ordered items, and it boosted the performance. The set having the same internal tree structure as the map, I guess the same boost would apply here ) 在我一年前工作的一个项目中,我们用一组相同的有序项目替换了一个有序项目列表,它提升了性能。具有与地图相同的内部树结构的集合,我猜同样的提升会在这里申请

(Edited after clarification) (澄清后编辑)

std::map is optimized for fast searching. std::map针对快速搜索进行了优化。 It has its own find method that uses its internal structure to provide good performance.它有自己的find方法,利用其内部结构提供良好的性能。 In general, it will only inspect log(N) keys, where N is the number of items in the map.通常,它只会检查log(N)键,其中 N 是地图中的项目数。

std::list<std::pair> is a simple linked list, and so only supports element-by-element traversal. std::list<std::pair>是一个简单的链表,因此只支持逐个元素遍历。 You could use the separate std::find algorithm, or std::find_if with a custom predicate that only examines the first member to better match the semantics of std::map::find , but that would be very slow.可以使用单独的std::find算法或std::find_if与自定义谓词,该谓词仅检查第first成员以更好地匹配std::map::find的语义,但这会非常慢。 In fact, it will have to look at every pair in the list for any failed search, and will look at half on average for any successful one.事实上,对于任何失败的搜索,它都必须查看列表中的每一对,对于任何成功的搜索,它平均会查看一半。

std:pair holds exactly two objects. std:pair正好包含两个对象。 std:map hold a collection of paired objects. std:map保存成对对象的集合。

You cannot use find() on pair, because there is nothing to find.你不能在pair上使用find(),因为没有什么可找到的。 The object you want is either pair.First or pair.Second你想要的对象是pair.Firstpair.Second

UPDATE: Assuming you meant the difference between map<> and list<pair<> > : Map should be implemented for fast lookup on the key member.更新:假设您的意思是map<>list<pair<> >之间的区别:应该实现 Map 以快速查找key成员。 list has just a simple linear list. list只有一个简单的线性列表。 Looking up an item in a list requires running through the whole list.在列表中查找项目需要遍历整个列表。 However, std::find() will work on both.但是, std::find() 对两者都适用。

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

STL maps are associative arrays, usually implemented as hashmaps inside. STL 映射是关联数组,通常在内部实​​现为哈希映射。 If you want to get iterate over an STL map it'll return an STL pair.如果您想遍历 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;
}

I'd suggest googling and reading the complete STL API reference since STL (with the exception of storing booleans in vectors and other oddities like that) implements a lot of data structure functionality you'd want to use in any program without reinventing the wheel.我建议谷歌搜索并阅读完整的 STL API 参考,因为 STL(除了在向量中存储布尔值和其他类似的东西)实现了许多你想在任何程序中使用的数据结构功能,而无需重新发明轮子。

std::pair is just for grouping together exactly 2 objects (say, "coordinates on a page" is comprized of X and Y). std::pair 仅用于将 2 个对象组合在一起(例如,“页面上的坐标”由 X 和 Y 组成)。

std::map is a mapping from one set of objects to another. std::map 是从一组对象到另一组对象的映射。

There's no point of trying to use a find method on a pair, as what's the point of finding something in a list of two things of which you know the order to, even if that find method existed in a pair class which it does not.尝试在 pair 上使用 find 方法是没有意义的,因为在你知道顺序的两个事物的列表中找到一些东西有什么意义,即使该 find 方法存在于它不存在的 pair 类中。

However, you CAN use std::pair as a map value if that's what you want.但是,如果这是您想要的,您可以使用 std::pair 作为映射值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM