【问题标题】:Time complexity of lookup and then insertion in a std::map<std::string, std::set<std::string>>查找然后插入 std::map<std::string, std::set<std::string>> 的时间复杂度
【发布时间】:2022-10-22 04:37:05
【问题描述】:

所以我有一个图(std::map),它将字符串存储为键,值是字符串集(图中每个节点的邻接列表):

std::map&lt;std::string, std::set&lt;std::string&gt;&gt; graph

我的插入代码很简单:

graph[from].insert(to) 在哪里都是字符串。所以我插入在键关联的字符串集中.

对于这个插入位代码的平均和最坏情况时间复杂度,我认为它们是 O(x*log(V) * y*log(n)),其中 x 是字符串的长度, y 是字符串的长度, V 是图中的节点数,n 是图中的边数(我包括了字符串长度,因为我认为我们还必须考虑 std::string 比较,它是 O(任一字符串的长度)) ?

最好情况的时间复杂度要么与平均/最坏情况相同,要么是 O(x*y),如果我们很幸运并且地图和集合实现的红黑树的根节点是弦乐,分别 - 虽然,我对这个最没有信心。

我会很感激一些帮助。谢谢。

【问题讨论】:

  • 可能想和你几分钟前问这个确切问题的同学在一起。
  • @sweenish 我没有看到任何与最近提出的问题类似的问题,但我确实在几个小时前在这里询问了关于地图/集合中的标准插入/查找的问题。现在,这是一个有点复杂的问题。

标签: c++ stl time-complexity complexity-theory


【解决方案1】:

时间复杂度是在某些方面,例如关键比较。在std::mapstd::set 中查找键是在O(log n) 键比较中。如果您的键比较函数逐个字符比较两个字符串,那么您可以说在这种情况下找到一个键是在 O(s log n)s 键字符串的平均大小(而不仅仅是您要查找的键)。

在您的场景中,您首先在O(s log V) 中找到from,然后在O(t log N) 中插入tos是map中键字符串的平均大小,t是特定集合(from对应的集合)中键字符串的平均大小,V是map的大小(或顶点数),N 是特定集合的大小。

这是两个独立的步骤,这就是为什么我说“特定集合”而不是“地图中的所有集合”,因此总时间复杂度只是 O(s log V) + O(t log N)O(s log V + t log N)

如果您不知道要预先插入的集合的特征,那么您可以做更多的平均并最终得到O(s log V + u log(E/V)),其中u 是所有集合中键字符串的平均大小地图,E 是这些键的数量(边数)。提醒:这种复杂性是在字符比较方面。它可能有用也可能没用,特别是因为它有四个变量。

【讨论】:

  • 谢谢,我就是这么想的。还有一个问题:对于最佳情况下的时间复杂度,是否为 O(s + t*log(N)),其中 s 是“from”字符串的长度,t 是“to”字符串的长度?本质上,地图的根键(红黑树实现)是“来自”字符串,所以是 O(1)*string 搜索复杂度?
  • @Slash 第一步确实是最好情况下的一个关键比较,所以O(s)。如果您提供提示或者插入恰好位于树中的正确位置,那么第二步可能只是两个关键比较,所以O(t)。无论如何,两者仍然加在一起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2012-07-31
  • 2015-10-22
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多