Problem Description
KMP算法是字符串模式匹配算法中较为高效的算法之一,其在某次子串匹配母串失败时并未回溯母串的指针而是将子串的指针移动到相应的位置。严蔚敏老师的书中详细描述了KMP算法,同时前面的例子中也描述了子串移动位置的数组实现的算法。前面你已经实现了子串移动的数组,现在就来利用该数组来实现KMP模式匹配。
下面是相应的算法:
Input Description
3组字符串,每组字符串占一行。每行包含由空格分隔的两个字符串,字符串仅由英文小写字母组成且长度不大于100。
Output Description
每组数据输出1行,输出后一个字符串在前一个字符串中的位置,如果不匹配,则输出0。
Sample Input
string str
thisisalongstring isa
nosubstring subt
Sample Output
1
5
0
Hint
提示:
表示字符串的数据结构依然是字符数组。
总结:
KMP算法调用很简单,但难的是理解算法的思想。掌握算法的思想才能说是掌握算法。
我的想法:
我的代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;
#define MAXSIZE 100
void Get_nest(char *str, int *nest)
{
int i = 1;
//nest[0] = str[0];
nest[1] = 0;
int j = 0;
while (i < str[0])
{
if (j == 0 || str[i] == str[j])
{
i++;
j++;
nest[i] = j;
}
else
{
j = nest[j];
}
}
}
int Index_KMP(char *str1, char *str2, int *nest, int pos)
{
int i = pos;
int j = 1;
while (i <= str1[0] && j <= str2[0])
{
if (j == 0 || str1[i] == str2[j])
{
i++;
j++;
}
else
{
j = nest[j];
}
}
if (j > str2[0])
{
return i - str2[0];
}
else
{
return 0;
}
}
int main()
{
char str1[MAXSIZE] = {'0'};
char str2[MAXSIZE] = {'0'};
int nest[MAXSIZE];
int length1;
int length2;
while (scanf("%s", &str1[1]) != EOF)
{
scanf("%s", &str2[1]);
//求nest数组
length1 = strlen(str1);
str1[0] = length1 - 1;
length2 = strlen(str2);
str2[0] = length2 - 1;
Get_nest(str2, nest);
cout << Index_KMP(str1, str2, nest, 0) << endl;
}
return 0;
} #define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;
#define MAXSIZE 100
void Get_nest(char *str, int *nest)
{
int i = 1;
//nest[0] = str[0];
nest[1] = 0;
int j = 0;
while (i < str[0])
{
if (j == 0 || str[i] == str[j])
{
i++;
j++;
nest[i] = j;
}
else
{
j = nest[j];
}
}
}
int Index_KMP(char *str1, char *str2, int *nest, int pos)
{
int i = pos;
int j = 1;
while (i <= str1[0] && j <= str2[0])
{
if (j == 0 || str1[i] == str2[j])
{
i++;
j++;
}
else
{
j = nest[j];
}
}
if (j > str2[0])
{
return i - str2[0];
}
else
{
return 0;
}
}
int main()
{
char str1[MAXSIZE] = {'0'};
char str2[MAXSIZE] = {'0'};
int nest[MAXSIZE];
int length1;
int length2;
while (scanf("%s", &str1[1]) != EOF)
{
scanf("%s", &str2[1]);
//求nest数组
length1 = strlen(str1);
str1[0] = length1 - 1;
length2 = strlen(str2);
str2[0] = length2 - 1;
Get_nest(str2, nest);
cout << Index_KMP(str1, str2, nest, 0) << endl;
}
return 0;
}
#include <iostream>
#include <string.h>
using namespace std;
#define MAX 100
typedef struct
{
char ch[MAX + 1];
int length;
}SString;
void get_next(SString T, int *next)
{
int i = 1;
next[1] = 0;
int j = 0;
while (i < T.length)
{
if (j == 0 || T.ch[i] == T.ch[j])
{
++i;
++j;
next[i] = j;
}
else
{
j = next[j];
}
}
}
void Index_KMP(SString S, SString T, int pos)
{
int next[101];
int i = pos;
int j = 1;
get_next(T, next);
while (i < S.length && j < T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
{
++j;
++i;
}
else
{
j = next[j];
}
}
if (j >= T.length)
{
cout << i - T.length + 1<< endl;
}
else
{
cout << "0" << endl;
}
}
int main()
{
SString S, T;
while (scanf("%s %s", S.ch + 1, T.ch + 1) != EOF)
{
S.length = strlen(S.ch);
T.length = strlen(T.ch);
Index_KMP(S, T, 1);
}
return 0;
}