考虑 STL 容器操作的复杂性

Posted

技术标签:

【中文标题】考虑 STL 容器操作的复杂性【英文标题】:Considering complexity of STL container operations 【发布时间】:2015-05-30 01:36:27 【问题描述】:

在计算算法的复杂性时,我们是否考虑了 STL 容器操作的时间/空间复杂性?例如,给定以下代码 sn -p:

// str is an std::string, and size = str.size()
std::string res;
for (int i = 0; i < size; i++)  // size is some integer
    res += str[i];  

是上面代码sn-p的时间复杂度: O(size) 因为循环?

O(size^2):因为在每次循环迭代中我们都附加到一个 std::string 并且这是一个线性时间复杂度操作?

如果没有通用答案,我问的是我们在面试时需要考虑什么。是否有一种事实上的约定来考虑/忽略 STL 容器操作的时间/空间复杂性?

谢谢。

编辑

即使示例代码没有显示完整的图片,我的问题是在计算算法的复杂度时是否需要。

【问题讨论】:

追加到std::string 不是线性操作。它是摊销常数。 来自:cplusplus.com/reference/string/string/operator+=,复杂性:未指定,但通常在新字符串长度中达到线性。 @user1157812 那是不准确的。采用CharT 参数的operator+= 重载是摊销常数时间复杂度,因为std::string 存储它的长度并且不必每次都走到末尾来追加单个字符。它有时需要重新分配内存,这将涉及复制现有内容。 @user1157812:那是错误的。确实,std::basic_string 与其他容器相比有点未指定,但它的操作复杂性没有理由与std::vector 不同,而且我知道没有实现附加单个字符的复杂性是线性操作,没有理由。 @user1157812 你永远不应该使用 cplusplus.com:它充满了错误。 cppreference.com 是推荐的网站。 en.cppreference.com/w/cpp/string/basic_string/operator%2B%3D 表示 += 与 char 参数的复杂性是不变的。 【参考方案1】:

当然,您需要考虑各个操作的复杂性,无论它发生在您的代码中还是库函数中。事实上,标准 C++ 库指定了对其容器的操作的时间复杂度,以及它的算法的时间复杂度,以使您的计算成为可能。

在您的具体示例中,答案取决于字符串数组str[] 中各个str 元素的大小。如果每个元素字符串的长度大致为size,那么答案就是O(size2)。如果每个元素都有固定的大小,那么答案就是 O(size),因为常量长度可以从表达式中分解出来。

【讨论】:

短语“单个str元素的大小”是指str中每个字符的大小? @user1157812 我没有看到str 的声明,所以我假设它是一个字符串数组。如果是字符串,+= 应该是一个摊销线性。

以上是关于考虑 STL 容器操作的复杂性的主要内容,如果未能解决你的问题,请参考以下文章

STL - STL容器的适用情况

总结stl(以后还会慢慢补上

在stl容器中移除元素的恒定时间

STL关联容器

STL关联容器

STL中的set容器的一点总结