考虑 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 容器操作的复杂性的主要内容,如果未能解决你的问题,请参考以下文章