最近在重新学习数据结构,字符串KMP算法的实现写了下,一同分享。 // 失配函数 // pat 模式字符串 // patLength 字符串长度 // failResult 失配位置数组(长度为patLength) void Mismatch(const char *pat, int patLength, int *failResult) { // 第一个位置失配值为-1 failResult[0] = -1; // 用于记录前一个失配值 int preFailVal = 0; for (int j=1; j<patLength; j++) { // 得到前一个位置失配值 preFailVal = failResult[j-1]; // 若比较字符不等则继续向前比较失配位置的字符,直到相等或不存在失配值的位置停止 while (pat[j]!=pat[preFailVal+1] && preFailVal>=0) { preFailVal = failResult[preFailVal]; } // 若相等则当前失配值为前一个失配值+1 if (pat[j] == pat[preFailVal+1]) { failResult[j] = preFailVal + 1; } // 不相等则为-1 else { failResult[j] = -1; } } } // KMP模式匹配算法 // string 字符串 // pat 待查找模式 // 成功返回模式首字母出现的位置,失败返回-1 int KMPMatch(const char *string, const char *pat) { // 参数有效性 if (string==NULL || pat==NULL) { return -1; } // 计算字符串长度 int lenString = strlen(string); int lenPat = strlen(pat); // 比较长度 if (lenPat > lenString) { return -1; } // 分配失配值数组 int *pFailArray = new int[lenPat]; if (pFailArray == NULL) { return -1; } // 初始化失配值数组 for (int k=0; k<lenPat; k++) { pFailArray[k] = -1; } // 计算失配值 Mismatch(pat, lenPat, pFailArray); // 进行模式匹配 int nFindPos = -1; int i=0; int j=0; while (i<lenString && j<lenPat) { // 字符相等 if (string[i] == pat[j]) { i++; j++; } // 发生失配 else { if (j == 0) { i++; } else { j = pFailArray[j-1] + 1; } } nFindPos = (j==lenPat) ? (i-lenPat) : -1; } // 释放失配值数组空间 if (pFailArray != NULL) { delete[] pFailArray; pFailArray = NULL; } // 返回查找结果 return nFindPos; }