/*************************************************
* 串的模式匹配;BF+KMP(C语言源代码)
* 2021/8/23
**************************************8***********/
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct
{
char ch[MAXSIZE+1];
int length;
}SString;
//①串的赋值操作
void StringAssign(SString* s1, char s2[])
{
int i = 0;
while (s2[i] != '\0') // '\0' 是字符串的结束符,任何字符串之后都会自动加上'\0'
i++; //计算s2的长度
s1->length = i;
for (i = 0; i < s1->length; i++)
s1->ch[i+1] = s2[i]; //从第一个字符开始逐个字符赋值
}
/*②BF算法*/
int index_BF(SString *S, SString *T)
{
int i = 1, j = 1;
while (i <=S->length && j <=T->length)
{
if (S->ch[i] == T->ch[j])
{
i++;
j++;
}
else
{
i = i - j + 2;
j = 1;
}
}
if (j > T->length)
return (i - T->length);
else
return 0;
}
/*③在使用KMP算法前,先求next[]数组*/
void Get_Next(SString* T, int next[])
{
int i = 1; int j = 0;
next[1] = 0;
while (i < T->length)
{
if (j == 0 || T->ch[i] == T->ch[j])
{
i++; j++; next[i] = j;
}
else
j = next[j]; /*模式失配,模式串向前移动*/
}
}
/*④求修正后的nextval[]数组*/
void Get_Nextval(SString* T, int nextval[])
{
int i = 1; int j = 0;
nextval[1] = 0;
while (i < T->length)
{
if (j == 0 || T->ch[i] == T->ch[j])
{
i++; j++;
if (T->ch[i] != T->ch[j])nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j]; /*模式失配,模式串向前移动*/
}
}
/*⑤KMP算法*/
int index_KMP(SString *S, SString *T,int next[])
{
int i = 1, j = 1;
while (i <= S->length && j <= T->length)
{
if (j==0||S->ch[i] == T->ch[j])
{
i++;
j++;
}
else
{
j = next[j]; /*此处是KMP与BF的主要区别:1.i不用回溯 2.j不用回溯到j=1,而是回溯到效率更高的next[j]*/
}
}
if (j > T->length)
return (i- T->length);
else
return 0;
}
int main()
{
/*定义串指针*/
SString *s1= (SString*)malloc(sizeof(SString));
SString *t2 = (SString*)malloc(sizeof(SString));
/*定义字符串数组*/
char S1[] = "abcdefjh";
char T2[] = "defjh";
/*①串的赋值操作*/
StringAssign(s1,S1);
//printf("%c",s1->ch[1]);
StringAssign(t2, T2);
// printf("\n%c", t2->ch[1]);
/*②BF算法*/
int a = 0;
a=index_BF(s1,t2);
printf("模式串在主串的第%d个位置\n\n", a);
/*③在使用KMP算法前,先求next[]数组*/
int next[6] = {0,0,0,0,0,0};
Get_Next(t2, next);
printf("next[j]数组元素为:");
for (int i = 0; i < 5; i++)
{
printf("%d ", next[i+1]);
}
printf("\n\n");
/*④求修正后的nextval[]数组*/
int nextval[6] = { 0,0,0,0,0,0 };
Get_Next(t2, nextval);
printf("nextval[j]数组元素为:");
for (int i = 0; i < 5; i++)
{
printf("%d ", nextval[i + 1]);
}
printf("\n\n");
/*⑤在next[]数组下,使用KMP算法*/
int b = 0;
b = index_KMP(s1,t2, next);
printf("模式串在主串的第%d个位置\n\n", b);
/*⑤在nextval[]数组下,使用KMP算法*/
int c = 0;
c = index_KMP(s1, t2, nextval);
printf("模式串在主串的第%d个位置\n", c);
return 0;
}
串的模式匹配;BF+KMP(C语言源代码)
最新推荐文章于 2023-05-23 10:49:18 发布