最近在学习算法。刚学习完字符串匹配的几种算法:BF算法、MP算法:KMP算法,BM算法和BMH算法。参考的书籍是算法之美,原书的代码都是用C++写的。我不懂C++,只学过C#,这里就用C#做个总结(自己是个菜鸟,表达错误的地方,希望大家指正)。
1、BF算法
BF算法实现原理是:从主串和模式串的首位置开始,依次比较主串和模式串的各个位置,如果匹配错误,主串就返回第二个位置,模式串返回首位置,重新匹配。以此类推,直到模式串匹配成功,返回匹配成功的位置。如果没有发生匹配就返回-1。
代码如下:
public static int MatchStr(string s1, string s2,int n)
{
int i = n-1, j = 0; //n为匹配的起始位置
bool IsMatch=false ;
while (!IsMatch)
{
if (s1[i] == s2[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
//如果模式串匹配成功,j++,就会得到模式串长度的值。
if (j == s2.Length)
{
IsMatch = true;
n = i - j+1;
}
}
if (IsMatch)
{
Console.WriteLine("普通方法匹配成功");
}
else
{
n = -1;
Console.WriteLine("普通方法匹配失败");
}
return n;
}
2、MP算法
BF算法一旦匹配失败,i,j的值就会频繁的回溯,导致复杂度增大。MP算法避免的i值回溯,只利用j值的回溯进行匹配。
MP算法原理:模式串与主串进行匹配,进行到i处(模式串在j处)发现不匹配,如果模式串j处之前有前缀n个字符与主串i处
之前n个字符相匹配,则可将模式串j移动到n处,重新与i进行匹配(此时i的位置不变)即可。依次类推,直到匹配结束。
现在的问题就是求n的值为多少。
假设模式串与主串在i处不匹配(模式串在j处),那么说明主串的s1[i-j~i-1]的子串与模式串的s2[0~j-1]是匹配成功的。那么寻找
主串i之前的n个字符,等价于寻找模式串j之前的n个字符与模式串的前缀n个字符是相匹配的,即n的值与主串无关,只与模式串自
身的j位置有关。n的计算方法计算如下:假定模式串为(ababcabababc)