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

发布于 2024-09-12 20:53:12 字数 112 浏览 7 评论 0 原文

std::liststd::map 之间有什么区别?列表也有 find 方法吗?

What is the difference between std::list<std::pair> and std::map? Is there a find method for the list, too?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

奶茶白久 2024-09-19 20:53:12

std::map

  • 是一个关于键的有序结构(也就是说,当你迭代它时,键将始终增加)。
  • 支持唯一键 (Xs) 仅
  • 提供快速 find() 方法 (O(log n)),该方法通过以下方式查找键值对Key
  • 提供了一个索引运算符 map[key],它的速度也很快

std::list >

  • 是成对的 XY 的简单序列。它们保持您放入的顺序。
  • 可以保存任意数量的重复项
  • ,在 list 中查找特定键是 O(N) (没有特殊方法)
  • 提供 <代码>拼接方法。

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 (Xs) only
  • offers fast find() method (O(log n)) which finds the Key-Value pair by Key
  • offers an indexing operator map[key], which is also fast

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

  • is a simple sequence of paired Xs and Ys. 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)
  • offers the splice method.
埋情葬爱 2024-09-19 20:53:12

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::map

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

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

映射本质上是按提供的函子排序的,而列表会将 [A,B] 对保留在您放置它们的位置。这使得映射的插入为 O(log n),而列表内的原始插入是一个恒定的复杂性(搜索在哪里插入它是另一个问题)。

您可以使用成对列表来模拟映射的行为,但请注意,映射通常实现为项目树,而列表是项目的链式列表。因此,像二分法这样的算法在映射中比在列表中运行得更快。

因此,在映射中查找项目的时间复杂度为 O(log n),而在无序列表中查找项目的时间复杂度为 O(n)。如果列表是有序的,并且您想使用二分法,则不会获得预期的性能提升,因为无论如何遍历项目列表都是逐项完成的。

在我一年前从事的一个项目中,我们用一组相同的有序项目替换了有序项目列表,这提高了性能。我猜,该集合具有与地图相同的内部树结构同样的提升也适用于此处

std::pair

std::pair is a templated tuple-structure limited to 2 items, called first and second:

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::map

std::map is an templated associative container, associating keys and values together. 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

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

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

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

揽月 2024-09-19 20:53:12

std:pair 恰好包含两个对象。 std:map 保存配对对象的集合。

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

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

std:pair holds exactly two objects. std:map hold a collection of paired objects.

You cannot use find() on pair, because there is nothing to find. The object you want is either pair.First or pair.Second

UPDATE:
Assuming you meant the difference between map<> and list<pair<> >: Map should be implemented for fast lookup on the key member. list has just a simple linear list. Looking up an item in a list requires running through the whole list. However, std::find() will work on both.

蓝眼泪 2024-09-19 20:53:12

(澄清后编辑)

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

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

(Edited after clarification)

std::map is optimized for fast searching. It has its own find method that uses its internal structure to provide good performance. In general, it will only inspect log(N) keys, where N is the number of items in the map.

std::list<std::pair> is a simple linked list, and so only supports element-by-element traversal. 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. 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.

以为你会在 2024-09-19 20:53:12

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(除了在向量中存储布尔值和其他类似的奇怪之处)实现了许多您希望在任何程序中使用的数据结构功能,而无需重新发明轮子。

STL maps are associative arrays, usually implemented as hashmaps inside. If you want to get iterate over an STL map it'll return an STL pair.

#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.

汐鸠 2024-09-19 20:53:12

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

Map can provide the better searching time in the range of O(log n),
whilw list can have the searching time of O(n).

紅太極 2024-09-19 20:53:12

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

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

尝试在pair上使用find方法是没有意义的,因为在知道顺序的两个事物的列表中查找某些东西有什么意义,即使该find方法存在于pair类中但它不存在。

但是,如果您想要的话,可以使用 std::pair 作为映射值。

std::pair is just for grouping together exactly 2 objects (say, "coordinates on a page" is comprized of X and Y).

std::map is a mapping from one set of objects to another.

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.

However, you CAN use std::pair as a map value if that's what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文