C++ 使用静态字符串值访问std::map时,访问时间是否仍然为O(logn)? std::map dict; 对于(int i=0;i

C++ 使用静态字符串值访问std::map时,访问时间是否仍然为O(logn)? std::map dict; 对于(int i=0;i,c++,performance,map,stl,std,C++,Performance,Map,Stl,Std,由于字符串值在编译时就已经知道了,编译器会在编译时对它们进行散列,而不是在运行时对这些字符串进行散列吗 编译器会在编译时对它们进行散列,而不是在运行时对这些字符串进行散列吗 不,因为std::map不使用哈希,它是一个红黑树或类似的二叉树 它每次都在树中执行查找 首先,编译器将“afsfgsdg”转换为std::string,然后在映射中对字符串进行O(logn)搜索。std::map不会散列任何内容。它使用比较来查找元素,其O(lg n)界用于当映射中有n个键时所需的比较次数。它并没有表达任何

由于字符串值在编译时就已经知道了,编译器会在编译时对它们进行散列,而不是在运行时对这些字符串进行散列吗

编译器会在编译时对它们进行散列,而不是在运行时对这些字符串进行散列吗

不,因为
std::map
不使用哈希,它是一个红黑树或类似的二叉树

它每次都在树中执行查找


首先,编译器将
“afsfgsdg”
转换为
std::string
,然后在映射中对字符串进行O(logn)搜索。

std::map
不会散列任何内容。它使用比较来查找元素,其O(lg n)界用于当映射中有n个键时所需的比较次数。它并没有表达任何关于比较本身的成本


也就是说,通过先进行指针比较,程序可能会使用一些短路字符串比较,但在最坏的情况下,比较的数量将保持对数(对于典型的红黑树实现,当项目位于树中的一个叶子上时)分析算法的渐近性能是研究必须执行的操作以及它们给方程增加的成本。为此,您需要首先了解所执行的操作,然后评估其成本

在平衡二叉树(映射恰好是)中搜索一个键需要O(logn)复杂的操作。这些操作中的每一个都意味着比较键是否匹配,如果键不匹配,则跟随相应的指针(子项)。这意味着总成本与log N乘以这两个操作的成本成正比。以下指针是一个常数时间操作O(1),比较键取决于键。对于整数键,比较是快速的O(1)。比较两个字符串是另一回事,它需要与所涉及的字符串大小成比例的时间O(L)(其中我故意使用L作为字符串的长度参数,而不是更常见的N)

当你把所有的代价加起来时,你会得到使用整数作为键的总代价是O(logn)*(O(1)+O(1)),这相当于O(logn)。(O(1)隐藏在O符号隐藏的常数中


如果使用字符串作为键,则总成本为O(logn)*(O(L)+O(1)),其中常数时间操作被成本更高的线性操作O(L)隐藏,并且可以转换为O(L*logn)也就是说,在由字符串键控的映射中查找元素的成本与映射中存储的元素数乘以用作键的字符串的平均长度的对数成正比。

查找为O(lg n)比较,n是键的数量。可能你想四处看看
std::unordered_map
所以map直接将键作为原始数据进行比较,当unordered map只是散列键时,我是对的吗?@jokoon:我不知道你所说的“原始数据”是什么意思。
map
使用
比较键,但比较的是原始键,而不是散列键。
std::map<string, int> dict;
for(int i = 0; i < 300; ++i)
{
    dict["afsfgsdg"] = i*i;
    dict["5t3rfb"] = i;
    dict["fddss"] = i-1;
    dict["u4ffd"] = i/3;
    dict["vgfd3"] = i%3;
}