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

标签 c++ string stl set time-complexity

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 ops/s。假设您的编译器使用 memcmp,这可能是手动矢量化的,具有像您这样的小型工作集,您完全从缓存中工作并且每次比较可以达到高达 512 字节的吞吐量(使用 AVX2 ).假设每次迭代 10 个周期的中等速率,我们仍然可以比较 >1010 字节/秒。因此,您的程序应该在 <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(log n),但比较字符串的复杂度为 O(n)。这些 n 不相同,在 map 的情况下,它表示 map 大小,在 string 的情况下 - 字符串的长度。

在您的特定情况下, map 只有一个元素,因此插入是 O(1)。纯粹从字符串比较中得到线性复杂度 O(n),其中 nstring_length * number_of_iterations

关于c++ - 将字符串插入到 C++ STL 集的时间复杂度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54381930/

相关文章:

用于高性能 FIFO 的 C++ 容器

c++ - 为什么 C++11 或 C++14 中没有位置迭代器?

c++ - 使用defalt args时,函数_main中引用的错误LNK2019无法解析的外部符号

c++ - 使用 boost phoenix,如何调用带有 starts_with 的 find_if 调用?

c++ - 将给定类型的任何枚举作为函数参数传递

javascript - 如何在字符串中找到第三个 "_"的位置 - JavaScript

c++ - 为什么这显示运行时错误?

string - 如何从 csv 字符串中获取 map

Python - 由于文件名中存在特殊字符而导致 "The system cannot find the file specified"

c++ - 两个 vector 的集合交集的高效或快速大小