在问题link中,我首先尝试使用字符数组。此解决方案超出了时间限制。
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秒的执行时间。为什么执行时间有这么大的差异?
答案 0 :(得分:4)
<nav>
<ul class="page-numbers">
<li><span class="page-numbers current">1</span></li>
<li><a class="page-numbers" href="http://xxx/page/2">2</a></li>
<li><a class="page-numbers" href="http://xxx/page/3">3</a></li>
<li><a class="next page-numbers" href="http://xxx/page/2">»</a></li>
</ul>
</nav>
分别存储其长度,因此std::string
是即时操作。
s.size()
在每次迭代时调用for(int i=0;i<strlen(s);++i)
,strlen(s)
遍历整个字符串到末尾以查找字符串的长度。所以这个看似无辜的循环实际上是O(n 2 )的复杂性。
答案 1 :(得分:1)
C字符串没有明确地存储长度,它们只有一个空的atbthe结尾。因此,要计算出长度,您需要逐个字符地迭代整个字符串。另一方面'sid :: string :: length'只返回内部存储的长度。
通过在循环之前缓存变量中的长度并在for语句中使用缓存长度,可以轻松加速C版本。