//KMP模式匹配算法
void get_next(string T, int* next) //計算出當前要匹配的串next數組
{
int i, j;
i = 1;
j = 0;
next[1] = 0;
while (i < T[0]) //此處T[0]表示串T的長度
{
if (j == 0 || T[i] == T[j]) //T[i]表示後綴的單個字符,T[j]表示前綴的單個字符
{
++i;
++j;
next[i] = j;
}
else
j = next[j]; //若字符不相同,則j值回溯
}
}
int Index_KMP(string S, string T, int pos)
{
int i = pos; //i用於主串S中當前位置下標,若pos不爲1,則從pos位置開始匹配
int j = 1; //j用於子串T中當前位置下標值
int next[255]; //定義一個next數組
get_next(T, next); //對串T作分析,得到next數組
while (i <= S[0] && j <= T[0]) //若i小於S長度且j小於T的長度時循環
{
if (j == 0 || S[i] == T[j]) //兩字母相等則繼續,與樸素算法增加了j=0判斷
{
++i;
++j;
}
else //指針後退重新開始匹配
{
j = next[j]; //j退回合適的位置,i值不變
}
}
if (j > T[0])
return i - T[0];
else
return 0;
}
//KMP模式匹配改進算法
void get_nextval(string T, int* nextval) //計算出當前要匹配的串next數組
{
int i, j;
i = 1;
j = 0;
nextval[1] = 0;
while (i < T[0]) //此處T[0]表示串T的長度
{
if (j == 0 || T[i] == T[j]) //T[i]表示後綴的單個字符,T[j]表示前綴的單個字符
{
++i;
++j;
if (T[i] != T[j]) //若當前字符與前綴字符不同
nextval[i] = j; //則當前的j爲nextval在i位置的值
else
nextval[i] = nextval[j]; //如果與前綴字符相同,則將前綴字符的nextval值賦給nextval在i位置的值
}
else
j = nextval[j]; //若字符不相同,則j值回溯
}
}
int Index_KMP(string S, string T, int pos)
{
int i = pos; //i用於主串S中當前位置下標,若pos不爲1,則從pos位置開始匹配
int j = 1; //j用於子串T中當前位置下標值
int next[255]; //定義一個next數組
get_nextval(T, next); //對串T作分析,得到next數組
while (i <= S[0] && j <= T[0]) //若i小於S長度且j小於T的長度時循環
{
if (j == 0 || S[i] == T[j]) //兩字母相等則繼續,與樸素算法增加了j=0判斷
{
++i;
++j;
}
else //指針後退重新開始匹配
{
j = next[j]; //j退回合適的位置,i值不變
}
}
if (j > T[0])
return i - T[0];
else
return 0;
}
KMP算法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.