PTA题目:使用KMP算法,在一个字符串s中查找子串t出现次数。字符串的匹配忽略大小写。字符串长度不超过1000。
如,s=“abcabcaBcd”,t=“abcaB”。这里认为t在s中出现2次。
注意:题目中已经给出模式串t的next数组值。
输入格式:
第一行输入字符串s
第二行输入字符串t
第三行给出串t的next数组值。包括next[0]~next[t.length-1]
输出格式:
第一行输出串t在s中出现的次数。 接下来每行输出串t在s中出现的位置序号(逻辑序号,从1开始计数)。
输入样例:
在这里给出一组输入。例如:
Abcabcabcd
abcab
-1 0 0 0 1
结尾无空行
输出样例:
在这里给出相应的输出。例如:
2
1
4
结尾无空行
代码:注意运行时间有限制,需要多次提交才能在规定时间内输出
#include<iostream>
#include<cstring>
using namespace std;
typedef char str[1001];
int index(str s1, str s2, int* next, int* pos, int& n) {
int b = 0;
int j = 0;
int ls1 = strlen(s1), ls2 = strlen(s2);
while ( b <ls1 && j<ls2 ) {
if (j == -1 || s1[b] == s2[j]|| abs(s1[b] - s2[j]) == 32) { ++b; ++j; }
else { j = next[j]; }
if (abs(j) == ls2 - 1) { pos[n] = b - ls2 + 2; n++; j = next[j];}//j = 0; b = b - ls2 + 2;
}
return 0;
}
int main() {
ios::sync_with_stdio(false);
str s1, s2;
int pos[100] = {};
int next[100] = {};
int i = 1;//输入字符串,子串 ,next数组
cin >> s1 >> s2;
int a = strlen(s2);
for (i = 0; i < a; i++) {
cin >> next[i];
}
int n = 0;//n是出现的次数
i = 0;
index(s1, s2, next, pos, n);
//输出n ,位置序号
cout << n << endl;
for (i = 0; i < n; i++) {
cout << pos[i] << endl;
}
return 0;
}