模式匹配KMP

来源:互联网 发布:阿里妈妈淘宝客赚钱 编辑:程序博客网 时间:2024/05/24 05:11

字符串朴素模式匹配算法的2种实现:

//1.朴素的模式匹配算法,用while实现

int StrStr_While(const char* pStr, const char* pSub, int* pos){int nRet = 0;int pStrLen = strlen(pStr);int pSubLen = strlen(pSub);int i = 0, j = 0;int nLen = pStrLen - pSubLen;if (pStr == NULL || pSub == NULL){nRet = -1;printf("param input error!");return nRet;}while (i < pStrLen && j < pSubLen){if (*(pStr + i) == *(pSub + j)){++i;++j;}else{i = i - j + 1;j = 0;}}if (j == pSubLen)*pos = i - j + 1;return nRet;}


 

//2.朴素的模式匹配,用for循环实现

int StrStr_For(const char* pStr, const char* pSub, int* pos){int nRet = 0;int pStrLen = strlen(pStr);int pSubLen = strlen(pSub);int i = 0, j = 0;int nLen = pStrLen - pSubLen;if (pStr == NULL || pSub == NULL){nRet = -1;printf("param input error!");return nRet;}for (i = 0; i <= nLen; ++i){for (j = 0; j < pSubLen; ++j){if (*(pStr + i + j) != *(pSub + j))break;}if (j == pSubLen){*pos = i + 1;break;}}return nRet;}


 

实现字符串的匹配有高效的算法,那就是KMP算法,实现如下:

//取得KMP算法需要用的的next数组

int GetNext(const char* pStr, int nNext[]){int nRet = 0;if (pStr == NULL || nNext == NULL){nRet = -1;printf("param input error!\n");return nRet;}int nLen = strlen(pStr);int i = 0, j = -1;nNext[i] = j;while (i < nLen - 1){if (j == -1 || pStr[i] == pStr[j]){++i;++j;nNext[i] = j;}else{j = nNext[j];}}return nRet;}//取next数组的改进型算法!剔除多个重复字符的next数组值持续增长!int GetNextVal(const char* pStr, int nNext[]){int nRet = 0;if (pStr == NULL || nNext == NULL){nRet = -1;printf("param input error!\n");return nRet;}int nLen = strlen(pStr);int i = 0, j = -1;nNext[i] = j;while (i < nLen - 1){if (j == -1 || pStr[i] == pStr[j]){++i;++j;if (pStr[i] != pStr[j])nNext[i] = j;elsenNext[i] = nNext[j];}else{j = nNext[j];}}return nRet;}


 

这是针对类似aaaaaaab这样的字符串使用上面两个函数取得的next数组值得比较。注意书上的都是字符串从数组的下标为1的位置开始存储的。我改进的算法是还是让字符串从数组下标为0的位置开始存储。所以上面的next数组值都要相较与原来的值减1。

 

//调用上面的函数实现KMP高效字符串模式匹配算法!


int Index_KMP(const char* pStr, const char* pSub, int* nPos){int nRet = 0;if (pStr == NULL || pSub == NULL || nPos == NULL){nRet = -1;printf("param input error!\n");return nRet;}int pStrlen = strlen(pStr);int pSublen = strlen(pSub);int nNext[255] = { 0 };//nRet = GetNext(pSub,nNext);nRet = GetNextVal(pSub, nNext);if (nRet != 0){printf("call GetNext() func is error!\n");return nRet;}int i = 0, j = 0;while (i < pStrlen && j < pSublen){if (j == -1 || *(pStr + i) == *(pSub + j)){++i;++j;}else{j = nNext[j];}}if (j == pSublen)*nPos = i - j + 1;return nRet;}


 

 

0 0
原创粉丝点击