将字符串插入到c++stl集的时间复杂度

Time Complexity of inserting string to c++ stl set

本文关键字:时间复杂度 c++stl 字符串 插入      更新时间:2023-10-16

将字符串插入到c++STL的容器集的时间复杂度是多少?根据我的说法,它应该是O(xlogn),其中x是要插入的字符串的长度,n是集合的大小。同时,将字符串复制到集合的长度应该是线性的。但我的这个代码正在立即运行。

#include<bits/stdc++.h>
using namespace std;
int main(){
set<string> c;
string s(100000,'a');
for(int i=0;i<100000;i++){
c.insert(s);
}
}   

我错在哪里了,复杂性不应该是10^10的数量级吗?

您应该以某种方式使用set来降低循环被优化的风险,例如添加return c.size();

此外,您对迭代次数的选择可能过低。在循环计数器上加一个数字,你会看到一个明显的运行时间。

现代CPU可以轻松处理>2*109操作/s。假设您的编译器使用memcmp,它可能是手动矢量化的,并且有一个像您这样的小工作集,那么您完全从缓存中工作,并且每次比较可以达到高达512字节的吞吐量(使用AVX2)。假设每次迭代10个周期的适度速率,我们仍然可以比较>1010字节/s。所以你的程序应该在<1在中等硬件上。

请尝试此更新代码:

#include <string>
#include <set>
using namespace std;
int main(){
set<string> c;
string s(100000,'a');
for(int i=0;i<1000000;i++) { // Add a digit here
c.insert(s);
}
return c.size(); // use something from the set
}

在启用优化(-O3)的情况下,在我的系统上运行大约需要5秒。

换句话说,是的,插入二叉树具有O(logn)复杂性,但是比较字符串具有O(n)复杂性。这n不相同,在map的情况下,它表示映射大小,在string的情况下表示字符串的长度。

在您的特定情况下,贴图只有一个元素,因此插入是O(1)。纯粹从字符串比较中获得线性复杂度O(n),其中n字符串长度*迭代次数