您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】字符串匹配

2015-06-26 16:07 549 查看
算法代码如下,包括暴力匹配和KMP算法。

参考 http://blog.csdn.net/v_july_v/article/details/7041827
#include "StringMatching.h"

StringMatching::StringMatching(void)
{
}

StringMatching::~StringMatching(void)
{
}

/*返回子串T在主串S中第pos个字符串之后的位置。若不存在,则返回0*/
int StringMatching::SimpleStringMatch(char* S ,char* T,int pos)
{
int sLen = strlen(S);
int tLen = strlen(T);

int i = pos; //i用于主串S中当前位置下标。若pos不为1,则从pos位置开始匹配
int j = 0 ;  //j用于子串T中当前位置下标值

while(i < sLen && j < tLen)
{
if (S[i] == T[j])
{
i++;
j++;
}
else
{
i = i-j+1;//i退回到上次匹配首位的下一位
j = 0;

}
}
if (j == tLen)
return i - j;
else
return -1;

}

//KMP模式匹配算法
/*通过计算返回子串T的next数组*/
void StringMatching::get_next(char* T,int *next)
{
int tLen = strlen(T);
int j,k;
j = 0;
k = -1;
next[0] = -1;
while (j < tLen)
{
if (k == -1 || T[j] == T[k])
{
j++;
k++;
next[j] = k;
}
else
{
k = next[k] ;//若字符不相同,则j值回溯
}
}
}

//改良后的KMP算法,只改进next数组的推导
/*通过计算返回子串T的next数组*/
void StringMatching::get_nextval(char* T,int *nextval)
{
int tLen = strlen(T);
int j,k;
j = 0;
k = -1;
nextval[0] = -1;
while (j < tLen)  //此处T[0]表示串T的长度
{
if (k == -1 || T[j] == T[k])
{
j++;
k++;
if (T[j] != T[k])
nextval[j] = k;
else
nextval[j] = nextval[k];  //如果与前缀字节相同,则将前缀字节的nextval值赋给i位置的值
}
else
{
k = nextval[k] ;//若字符不相同,则j值回溯
}
}
}

//flag不为0是改善后的KMP
int StringMatching::KMP(char* S,char* T ,int pos,int flag)
{
int sLen = strlen(S);
int tLen = strlen(T);

int i = pos ;
int j = 0;
int next[255];

if (flag == 0)
{
get_next(T ,next);
}
else
{
get_nextval(T ,next);
}

while (i < sLen && j < tLen)
{
if (j == -1 || S[i] == T[j])
{
i++;
j++;
}
else
{
j = next[j]; //j退回合适的位置,i不变
}
}

if (j == tLen)
return i - j;
else
return 0;
}


测试代码如下
void TEST_StringMatch()
{
char* p = "I am very unhappy!";
char* T = "happy";
StringMatching st;
int resultSimpleStringMatch = st.SimpleStringMatch(p,T,0);
int resultKMP = st.KMP(p,T,0,0);
int resultKMP_2 = st.KMP(p,T,0,1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: