一、简单的模式匹配算法(BF)
思路如下
Java 实现
// 简单的模式匹配算法
public class BF {
public static int indexBF(char s[],char p[]){
int i=0,j=0;
while(i<s.length&&j<p.length){
if(s[i]==p[j]){
i++;
j++;
}else{
i=i-j+1;
j=0;
}
}
if(j>=p.length){
return i-p.length;
}else{
return -1;
}
}
public static void main(String[] args) {
char s[] = {\'a\',\'b\',\'a\',\'b\',\'c\',\'a\',\'b\',\'c\',\'a\',\'c\',\'b\',\'a\',\'b\'};
char p[] = {\'b\',\'c\',\'a\'};
int index = indexBF(s,p);
System.out.println(index);
}
}
C++ 实现
#include <iostream>
#include <string>
using namespace std;
int indexBF(string S, string T){
if (S.size() < 1 || T.size() < 1)
return -1;
int i = 0, j = 0;
while (i < S.size() && j < T.size()){
if (S[i] == T[j]){
i++;
j++;
}else{
i = i- j+ 1;
j = 0;
}
}
if(j==T.size()) return i - j;
return -1;
}
int main(){
string S= "ababcabcacbab";
string T = "cacb";
int index = indexBF(S,T);
cout<<index<<endl;
return 0;
}
二、KMP 算法
C++ 实现
#include <iostream>
#include <string>
using namespace std;
/* P 为模式串,下标从 0 开始 */
void GetNext(string P, int next[])
{
int p_len = P.size();
int i = 0; // P 的下标
int j = -1;
next[0] = -1;
while (i < p_len)
{
if (j == -1 || P[i] == P[j])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
}
/* 在 S 中找到 P 第一次出现的位置 */
int KMP(string S, string P, int next[])
{
GetNext(P, next);
int i = 0; // S 的下标
int j = 0; // P 的下标
int s_len = S.size();
int p_len = P.size();
while (i < s_len && j < p_len)
{
if (j == -1 || S[i] == P[j]) // P 的第一个字符不匹配或 S[i] == P[j]
{
i++;
j++;
}
else
j = next[j]; // 当前字符匹配失败,进行跳转
}
if (j == p_len) // 匹配成功
return i - j;
return -1;
}
int main()
{
int next[100] = { 0 };
cout << KMP("bbc abcdab abcdabcdabde", "abcdabd", next) << endl; // 15
return 0;
}
next() 函数
未优化版
/* P 为模式串,下标从 0 开始 */
void GetNext(string P, int next[])
{
int p_len = P.size();
int i = 0; // P 的下标
int j = -1;
next[0] = -1;
while (i < p_len)
{
if (j == -1 || P[i] == P[j])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
}
优化版
/* P 为模式串,下标从 0 开始 */
void GetNextval(string P, int nextval[])
{
int p_len = P.size();
int i = 0; // P 的下标
int j = -1;
nextval[0] = -1;
while (i < p_len)
{
if (j == -1 || P[i] == P[j])
{
i++;
j++;
if (P[i] != P[j])
nextval[i] = j;
else
nextval[i] = nextval[j]; // 既然相同就继续往前找真前缀
}
else
j = nextval[j];
}
}
参考资料