c++中字符串和字符数组声明的时间复杂度有什么不同?

What is the difference between time complexity of string and char array declarations in c++?

本文关键字:时间复杂度 什么 声明 字符串 字符 数组 c++      更新时间:2023-10-16

在问题链接中,我首先尝试使用字符数组。此解决方案超出了时间限制。

    char s[100000];
    cin >> s;
    int cnt[26];
    for(int i=0;i<26;++i)
        cnt[i]=0;
    for(int i=0;i<strlen(s);++i)
        cnt[s[i]-'a']++;
    int count =0;
    for(int i=0;i<26;++i)
        if(cnt[i]>0)
            count++;
    cout << count << endl;

但是之后我把上面的代码改成了:

    string s;
    cin >> s;
    int cnt[26];
    for(int i=0;i<26;++i)
        cnt[i]=0;
    for(int i=0;i<s.length();++i)
        cnt[s.at(i)-'a']++;
    int count =0;
    for(int i=0;i<26;++i)
        if(cnt[i]>0)
            count++;
    cout << count << endl;

代码很容易通过。而且第一个也超过了1秒的时限,而第二个超过了0.04秒的时限。为什么执行时间有这么大的差异?

std::string单独存储其长度,因此s.size()是一个即时操作。

for(int i=0;i<strlen(s);++i)在每次迭代中调用strlen(s), strlen循环遍历整个字符串直到字符串的末尾以找到字符串的长度。所以这个看起来无害的循环实际上是O(n2)复杂度。

C字符串不显式地存储长度,它们只是在末尾有一个null。所以要算出长度,你需要一个字符一个字符地遍历整个字符串。'sid::string::length'则返回内部存储的长度。

你可以很容易地加快C版本的速度,通过在循环之前缓存长度在一个变量中,并在for语句中使用缓存的长度。