/*******************************************************************************
/* <PRE>
/* 版权所有 : -
/* 模块名 : 串
/* 文件名 : string.cpp
/* 功能描述 : 串的模式匹配
/* 作者 : <xxx>
/* 版本 : 1.0
/* -----------------------------------------------------------------------------
/* 备注 : -
/* -----------------------------------------------------------------------------
/* 修改记录 :
/* 日 期 版本 修改人 修改内容
/* 2011/01/01 1.0 <xxx> 创建
/* </PRE>
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string>
/******************************************************************************
/* 数据结构声明
/******************************************************************************/
/* 串的定长顺序存储表示 */
#define MAXSTRLEN 255 /* 用户可以在255以内定义最大串长 */
typedef unsigned char SString[MAXSTRLEN + 1]; /* 0号单元存放串的长度 */
/******************************************************************************
/* 函数原型声明
/******************************************************************************/
void get_next(SString T, int next[]);
void get_nextval(SString T, int nextval[]);
/*******************************************************************************
/* <FUNC>
/* 函数名 : Index
/* 功能 : 求子串位置
/* 参数 : -
/* 返回值 : -
/* 备注 : 返回子串T在主串S中第pos个字符之后的位置。若不存在, 则函数值为0
/* 其中, T非空, 1 <= pos <= StrLength(S)
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
int Index(SString S, SString T, int pos) {
int i = pos; int j = 1;
while (i <= S[0] && j <= T[0]) {
if (S[i] == T[j]) {++i; ++j;} //继续比较后继字符
else {i = i - j + 2; j = 1;} //指针后退重新开始匹配
}
if (j > T[0]) return i - T[0];
else return 0;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Index_KMP_1
/* 功能 : 求子串位置的KMP算法1
/* 参数 : -
/* 返回值 : -
/* 备注 : 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法
/* 其中, T非空, 1 <= pos <= StrLength(S)
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
int Index_KMP_1(SString S, SString T, int pos) {
int i = pos; int j = 1;
int *next = (int *)malloc((T[0] + 1) * sizeof(int));
get_next(T, next);
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) {++i; ++j;} //继续比较后继字符
else j = next[j]; //模式串向右移动
}
free(next);
if (j > T[0]) return i - T[0]; //匹配成功
else return 0;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : get_next
/* 功能 : 求next函数值
/* 参数 : -
/* 返回值 : -
/* 备注 : 求模式串T的next函数值, 并存入数组next
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void get_next(SString T, int next[]) {
int i = 1, j = 0; next[1] = 0;
while (i < T[0]) {
if (j == 0 || T[i] == T[j]) {++i; ++j; next[i] = j;}
else j = next[j];
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Index_KMP_2
/* 功能 : 求子串位置的KMP算法2
/* 参数 : -
/* 返回值 : -
/* 备注 : 利用模式串T的nextval函数求T在主串S中第pos个字符之后的位置的KMP算法
/* 其中, T非空, 1 <= pos <= StrLength(S)
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
int Index_KMP_2(SString S, SString T, int pos) {
int i = pos; int j = 1;
int *nextval = (int *)malloc((T[0] + 1) * sizeof(int));
get_nextval(T, nextval);
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) {++i; ++j;} //继续比较后继字符
else j = nextval[j]; //模式串向右移动
}
free(nextval);
if (j > T[0]) return i - T[0]; //匹配成功
else return 0;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : get_nextval
/* 功能 : 求nextval函数值
/* 参数 : -
/* 返回值 : -
/* 备注 : 求模式串T的next函数值修正值并存入数组nextval
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void get_nextval(SString T, int nextval[]) {
int i = 1; nextval[1] = 0; int j = 0;
while (i < T[0]) {
if (j == 0 || T[i] == T[j]) {
++i; ++j;
if (T[i] != T[j]) nextval[i] = j;
else nextval[i] = nextval[j];
}
else j = nextval[j];
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : main
/* 功能 : 测试函数
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void main()
{
SString S, T;
S[0] = strlen("ababcabcacbab");
T[0] = strlen("abcac");
strcpy((char *)&S[1], "ababcabcacbab");
strcpy((char *)&T[1], "abcac");
printf("Index: %d\n", Index(S, T, 1));
printf("Index_KMP_1: %d\n", Index_KMP_1(S, T, 1));
printf("Index_KMP_2: %d\n", Index_KMP_2(S, T, 1));
}
/* <PRE>
/* 版权所有 : -
/* 模块名 : 串
/* 文件名 : string.cpp
/* 功能描述 : 串的模式匹配
/* 作者 : <xxx>
/* 版本 : 1.0
/* -----------------------------------------------------------------------------
/* 备注 : -
/* -----------------------------------------------------------------------------
/* 修改记录 :
/* 日 期 版本 修改人 修改内容
/* 2011/01/01 1.0 <xxx> 创建
/* </PRE>
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string>
/******************************************************************************
/* 数据结构声明
/******************************************************************************/
/* 串的定长顺序存储表示 */
#define MAXSTRLEN 255 /* 用户可以在255以内定义最大串长 */
typedef unsigned char SString[MAXSTRLEN + 1]; /* 0号单元存放串的长度 */
/******************************************************************************
/* 函数原型声明
/******************************************************************************/
void get_next(SString T, int next[]);
void get_nextval(SString T, int nextval[]);
/*******************************************************************************
/* <FUNC>
/* 函数名 : Index
/* 功能 : 求子串位置
/* 参数 : -
/* 返回值 : -
/* 备注 : 返回子串T在主串S中第pos个字符之后的位置。若不存在, 则函数值为0
/* 其中, T非空, 1 <= pos <= StrLength(S)
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
int Index(SString S, SString T, int pos) {
int i = pos; int j = 1;
while (i <= S[0] && j <= T[0]) {
if (S[i] == T[j]) {++i; ++j;} //继续比较后继字符
else {i = i - j + 2; j = 1;} //指针后退重新开始匹配
}
if (j > T[0]) return i - T[0];
else return 0;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Index_KMP_1
/* 功能 : 求子串位置的KMP算法1
/* 参数 : -
/* 返回值 : -
/* 备注 : 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法
/* 其中, T非空, 1 <= pos <= StrLength(S)
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
int Index_KMP_1(SString S, SString T, int pos) {
int i = pos; int j = 1;
int *next = (int *)malloc((T[0] + 1) * sizeof(int));
get_next(T, next);
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) {++i; ++j;} //继续比较后继字符
else j = next[j]; //模式串向右移动
}
free(next);
if (j > T[0]) return i - T[0]; //匹配成功
else return 0;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : get_next
/* 功能 : 求next函数值
/* 参数 : -
/* 返回值 : -
/* 备注 : 求模式串T的next函数值, 并存入数组next
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void get_next(SString T, int next[]) {
int i = 1, j = 0; next[1] = 0;
while (i < T[0]) {
if (j == 0 || T[i] == T[j]) {++i; ++j; next[i] = j;}
else j = next[j];
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : Index_KMP_2
/* 功能 : 求子串位置的KMP算法2
/* 参数 : -
/* 返回值 : -
/* 备注 : 利用模式串T的nextval函数求T在主串S中第pos个字符之后的位置的KMP算法
/* 其中, T非空, 1 <= pos <= StrLength(S)
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
int Index_KMP_2(SString S, SString T, int pos) {
int i = pos; int j = 1;
int *nextval = (int *)malloc((T[0] + 1) * sizeof(int));
get_nextval(T, nextval);
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) {++i; ++j;} //继续比较后继字符
else j = nextval[j]; //模式串向右移动
}
free(nextval);
if (j > T[0]) return i - T[0]; //匹配成功
else return 0;
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : get_nextval
/* 功能 : 求nextval函数值
/* 参数 : -
/* 返回值 : -
/* 备注 : 求模式串T的next函数值修正值并存入数组nextval
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void get_nextval(SString T, int nextval[]) {
int i = 1; nextval[1] = 0; int j = 0;
while (i < T[0]) {
if (j == 0 || T[i] == T[j]) {
++i; ++j;
if (T[i] != T[j]) nextval[i] = j;
else nextval[i] = nextval[j];
}
else j = nextval[j];
}
}
/*******************************************************************************
/* <FUNC>
/* 函数名 : main
/* 功能 : 测试函数
/* 参数 : -
/* 返回值 : -
/* 备注 : -
/* 作者 : <xxx>
/* </FUNC>
*******************************************************************************/
void main()
{
SString S, T;
S[0] = strlen("ababcabcacbab");
T[0] = strlen("abcac");
strcpy((char *)&S[1], "ababcabcacbab");
strcpy((char *)&T[1], "abcac");
printf("Index: %d\n", Index(S, T, 1));
printf("Index_KMP_1: %d\n", Index_KMP_1(S, T, 1));
printf("Index_KMP_2: %d\n", Index_KMP_2(S, T, 1));
}
【参考】