#include<iostream> using namespace std; int main(){ string s1,s2; int index = 0;//找到的s1的下标 int step=0;//剩余长度 int s1_len = s1.length(); int cnt = 0;//计算目标出现次数 getline(cin,s1);//短的 getline(cin,s2);//长的 while(s2!=""){ if(s2.find(s1)!=string::npos){ index = s2.find(s1); cnt++; }else{ break; } step = s2.length()-(index+s1.length()); if(step>0) s2 = s2.substr(index+s1.length(),step); } cout<<cnt; return 0; }如何优化时间复杂度
时间: 2024-02-14 13:13:27 浏览: 61
首先需要指出的是,给出的代码存在一些问题,例如没有初始化字符串s1和s2,以及在循环中s2没有更新等。为了方便讨论,我假设s1和s2已经正确初始化,并在每次循环中更新了s2的值。
接下来,我们来看如何优化时间复杂度。当前的代码使用了s2.find(s1)函数来查找s1在s2中的位置,但这个函数的时间复杂度是O(nm),其中n和m分别表示s2和s1的长度。因此,如果s2非常长,而s1非常短,那么这个算法的时间复杂度就会很高。
一种优化的方法是使用KMP算法来查找s1在s2中的位置。KMP算法的时间复杂度是O(n+m),其中n和m分别表示s2和s1的长度,与s2的长度无关。因此,如果s2非常长,而s1非常短,那么KMP算法的效率会明显优于s2.find(s1)函数。
具体实现可以参考下面的代码:
```c++
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<int> getNext(string s) {
int n = s.length();
vector<int> next(n, 0);
for (int i = 1, j = 0; i < n; ++i) {
while (j > 0 && s[i] != s[j]) {
j = next[j - 1];
}
if (s[i] == s[j]) {
++j;
}
next[i] = j;
}
return next;
}
int kmp(string s1, string s2) {
int cnt = 0;
int n = s2.length(), m = s1.length();
vector<int> next = getNext(s1);
for (int i = 0, j = 0; i < n; ++i) {
while (j > 0 && s2[i] != s1[j]) {
j = next[j - 1];
}
if (s2[i] == s1[j]) {
++j;
}
if (j == m) {
++cnt;
j = next[j - 1];
}
}
return cnt;
}
int main() {
string s1, s2;
getline(cin, s1);
getline(cin, s2);
int ans = kmp(s1, s2);
cout << ans << endl;
return 0;
}
```
在上述代码中,我们使用了getNext函数来计算s1的next数组,然后使用kmp函数来查找s1在s2中的位置。其中,变量cnt用于记录s1在s2中出现的次数。
希望这个解答能够对您有所帮助。
阅读全文