前言:
21考研,不论能否进复试记录一下准备路上写下的垃圾代码。本来啃《算法笔记》,但是感觉太多了做不完,改做王道机试指南。
题目描述:
Finding all occurrences of a pattern in a text is a problem that arises frequently in text-editing programs. Typically,the text is a document being edited,and the pattern searched for is a particular word supplied by the user. We assume that the text is an array T[1…n] of length n and that the pattern is an array P[1…m] of length m<=n.We further assume that the elements of P and T are all alphabets(∑={a,b…,z}).The character arrays P and T are often called strings of characters. We say that pattern P occurs with shift s in the text T if 0<=s<=n and T[s+1…s+m] = P[1…m](that is if T[s+j]=P[j],for 1<=j<=m). If P occurs with shift s in T,then we call s a valid shift;otherwise,we calls a invalid shift. Your task is to calculate the number of vald shifts for the given text T and p attern P.
输入描述
For each case, there are two strings T and P on a line,separated by a single space.You may assume both the length of T and P will not exceed 10^6.
输出描述:
You should output a number on a separate line,which indicates the number of valid shifts for the given text T and pattern P.
解答
#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int MAXN = 1000 + 10;
void getnext(int next[], string t) {
int k = -1, j = 0;
next[0] = -1;
while (j < t.length() -1 )
if (k == -1 || t[k] == t[j])
next[++j] = ++k;
else
k = next[k];
return;
}
int KMP(string text,string t,int next[]) {
int i = 0, j = 0;
int count = 0;
while (i < (int)(text.length()) && j < (int)(t.length())) {
//注意一定要加强制类型转换,length()返回的是无符号数,若不加当j=-1,比较的时候j被转为无符号数,会变得很大,导致bug
if (j == -1 || text[i] == t[j]) {
i++;
j++;
}
else
j = next[j];
if (j == t.length()) {
i = i - j + 1;
j = 0;
count++;
}
}
return count;
}
int main() {
string text, pattern;
while (cin >> text >> pattern) {
int next[MAXN];
getnext(next, pattern);
cout << KMP(text, pattern, next) << endl;
}
return 0;
}
可以用STL的find()实现非常方便,但是今天刚学完KMP算法,还是想手动实现一下。string的length()返回的是无符号数这点真的太坑了,想了很久想不明白,还是请教了大佬才了解。