判断题:
1-1假设模式串是abababaab
,则KMP模式匹配算法中的next[j] = 0 1 1 2 3 4 5 6 2
(T) (2分)
解析:求next数组我们用前缀后缀最大公共元素长度进行手动求解。
在这里这个题目并没有说明串的存储下标是从0开始还是1开始。
如果是下标从0开始那么next数组就是-1 0 0 1 2 3 4 5 1。
如果是下标从1开始就是0 1 1 2 3 4 5 6 2。
选择题:
2-1设主串 T = abaabaabcabaabc
,模式串 S = abaabc
,采用 KMP 算法进行模式匹配,到匹配成功时为止,在匹配过程中进行的单个字符间的比较次数是:(3分)
- 9
- 10
- 12
- 15
解析:首先我们匹配。
i
a b a a b a a b c a b a a b c
a b a a b c
j
到此为止是6次,然后j回溯。
i
a b a a b a a b c a b a a b c
a b a a b c
j
之后再次匹配4次。
编程题:
7-1 【模板】KMP字符串匹配 (20 分)
给出两个字符串text和pattern,其中pattern为text的子串,求出pattern在text中所有出现的位置。
为了减少骗分的情况,接下来还要输出子串的前缀数组next。
输入格式:
第一行为一个字符串,即为text。
第二行为一个字符串,即为pattern。
输出格式:
若干行,每行包含一个整数,表示pattern在text中出现的位置。
接下来1行,包括length(pattern)个整数,表示前缀数组next[i]的值,数据间以一个空格分隔,行尾无多余空格。
输入样例:
ABABABC
ABA
输出样例:
1
3
0 0 1
样例说明:
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 5;
int Next[maxn];
string text, pattern;
void getNext()
{
int i = 0, j = -1;
Next[i] = j;
while(i < pattern.length())
{
if(j == -1 || pattern[j] == pattern[i])
Next[++i] = ++j;
else
j = Next[j];
}
}
void kmp()
{
int i = 0, j = 0;
while(i < text.size())
{
if(j == -1 || text[i] == pattern[j])
{
j++;
i++;
}
else
j = Next[j];
if(j == pattern.length())
{
cout << i - j + 1 << endl;
j = Next[j];
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> text >> pattern;
getNext();
kmp();
cout << Next[1];
for(int i = 2; i <= pattern.size(); i++)
cout << " " << Next[i];
cout << endl;
return 0;
}
解析:当模式串完全匹配之后,我们假设不匹配让j在next数组当中回溯就可以了。