std::map如何通过字符串查找元素

How does std::map find an element by string?

本文关键字:查找 元素 字符串 map std 何通过      更新时间:2023-10-16

在C++中,您可以使用std::map创建映射"容器"。

在我的例子中,键是字符串,元素是整数。(std::map<string, int>(

我想知道的是映射如何通过使用[]操作符来检索它们的元素用一根绳子。

映射是否只是将输入的字符串与其现有字符串键集的ALL与我声明的元素进行比较?如果是这样的话,那么如果我需要一种从一长串字符串中检索所需元素的最佳方式,那肯定会显得很慢。

按字符串进行索引的更快方法是为字符串中的每个字符使用256个相同类型链表的链表。这意味着为了检索元素,我所要做的就是说[char 1]->[char 2]->...[char n]->element.

在那里,速度将由字符串的长度决定,或者,无论你指向下一个字符多少次。

EDIT我刚才描述的这个过程被称为Trie,它不是std::map使用的

如果std::map<string, element_type>不使用这种方法,那么它是如何工作的?如果我碰巧添加了大量密钥,它值得使用吗?

如果我的问题似乎不清楚,请告诉我,这样我就可以更改它。我只需要知道地图中的键数量是否会减慢访问过程,以及地图如何匹配它们的元素。

std::map使用二进制搜索树。因此查找时间与log(n)成比例,其中n是映射中元素的数量。所以不,它并不慢。

另一种将字符串映射到值的方法是哈希映射,它通常但并不总是比二进制搜索树快。标准库也具有std::unordered_map形式的其中一个。

你在建议书中所描述的内容类似于尝试。标准库没有Trie类。请注意,虽然Trie适用于字符串键的特定情况,但二进制搜索树要通用得多,只需要对键进行排序。默认情况下,std::map使用operator<执行此排序。

正如其他人所说,std::map被实现为一个排序、平衡的二叉树,它的查找时间为O(log2N(。

这实际上意味着它可以进行二进制搜索:你所寻找的是按排序的"中间"元素吗?太棒了但如果它小于这个数,则在较小元素的子树中搜索,如果它大于较大元素的子树。重复,直到找到,或者你意识到元素根本不在树中。例如:

                        my_map: 37, left/less, right/greater
                                        /            
                                      22             68
                                     /             /  
                                    11   26        47  99
                                  /  |   |      /  |   | 
                                 5  13  24  33  39 49  78 nullptr

在这里,无论你想找到哪个数字,你都可以看到,你从比较37开始,如果它少,你就检查该根节点下的"较少"子树,如果它多,你就会检查"较大"子树:最坏的情况是,在你找到元素或意识到它不在树中之前,你最终会与4个数字进行比较。

为了让你对此有一些看法,如果你有1000个元素,那么最多需要10次比较(平均约9次(。这是因为log2(1000(恰好约为10-(2^10实际上是1024(。每有大约1000倍的元素,就会有大约10个比较:即100万个元素=>大约20个比较,10亿个=>大约30个,1万亿个=>大约40个。

字符串的比较通常速度相当快,尤其是如果字符串很短(几十个字符以下(,而且它们不仅仅在最后一个或三个字符中变化。


你的建议——trie——确实可以非常快——它们特别适合在键入提示时完成这样的事情,在提示中,你一次输入一个字符,并希望实时更新可能的匹配。但是,它们确实到处都有可能的字符大小的节点的单独阵列——有时额外的内存使用和随之而来的缓存页面故障可能会使天平向std::mapstd::unordered_map(哈希表(倾斜——如果你有分析证据表明你应该关心的话,实现每一个并进行比较。。。。

不,这不是将密钥与所有现有密钥进行比较。

std::map使用一种称为二进制搜索树的数据结构,通常是红黑树,在红黑树中查找元素非常有效。

红黑树的工作原理太宽泛了,请先阅读维基百科。

我认为std::map是作为一种称为红黑树的二进制搜索树实现的。它的复杂性是log(n)

请参阅此处了解更多详细信息:为什么std::map被实现为红黑树?