算法介绍
给定文本串text和模式串pattern,从文本串text中找出模式串pattern第一次出现的位置。
算法详解
基本的字符串匹配算法大致有一下集中方法
第一种:暴力法
代码部分:
void searchViolence(char *S, char *P) {
int i = 0;
int j = 0;
int sSize = strlen(S);
int pSize = strlen(P);
int start = 0;
int end = 0;
while ((i < sSize) && (j < pSize)) {
if (S[i + j] == P[j]) {
j++;
}
else {
i++;
j = 0;
}
}
if (j >= pSize) {
for (int k = i; k <i+j; k++) {
printf("%c", S[k]);
}
printf("\n");
}
}
第二种:KMP算法
该博客非常清晰描述了KMP算法的实现过程,本文就不做赘述了。
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
第一步:对于模式串的位置j,考察Pattern j-1 =p0,p1,...,pj-2,pj-1,查找字符串Pattern j-1的最大相等k前缀和k后缀。
第二步:对于模式串的位置j,有next[j]=k,即:p0,p1,...,pk-2,pk-1 = pj-k,pj-k+1,...,pj-2,pj-1
第三步:判断
1、若p[k]==p[j]
则next[j+1]=next[j]+1
2、若p[k]≠p[j]
记h=next[k];如果p[h]==p[j],则next[j+1]=h+1,
否则重复此过程。
代码如下:
void calcNext(char *P, int *N) {
int pSize = strlen(P);
N[0] = -1;
int k = -1;
int j = 0;
while (j < pSize - 1) {
// 若p[k]==p[j]则next[j+1]=next[j]+1
if (k == -1 || P[j] == P[k]) {
k++;
j++;
N[j] = k;
}
// 若p[k]≠p[j]则记h=next[k]
else {
k = N[k];
}
}
}
void KMP(char *S, char *P, int *N) {
int move = 0;
int i = 0;
int j = 0;
int pSize = strlen(P);
int sSize = strlen(S);
while (i < sSize) {
// 如果字符相等则一位一位比较
if (j == -1 || S[i] == P[j]) {
i++;
j++;
}
// 如果字符不相等,则根据next表进行移动
else {
j = N[j];
}
if (j == pSize) {
for (int k = i -j ; k < i; k++) {
printf("%c",S[k]);
}
printf("\n");
break;
}
}
}
参考资料: