今天学习了一下串的模式匹配算法,在这里记一下,以后好参考.具体的原理就不说了,可以参考严蔚敏老师的<<数据结构>>一书第79页到第84页,那里讲得比较深.我用C#写了一下这个算法,并且实现为string类的扩展函数.代码如下:
Code
using System;
class KMPClass
{
static void Main(string[] args)
{
string mother = "concatenation";
string child = "cat";
int k = mother.indexKMP(child);
Console.WriteLine(k);
Console.Read();
}
}
public static class MyClass
{
/**//// <summary>
/// 简单版本,效率低
/// </summary>
/// <param name="str"></param>
/// <param name="child"></param>
/// <returns></returns>
public static int index(this string str,string child)
{
int i = 0;
int j = 0;
while (i < str.Length && j < child.Length )
{
if (str[i] == child[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j >child.Length - 1)
{
return i - child.Length;
}
else
{
return -1;
}
}
/**//// <summary>
/// KMP算法
/// </summary>
/// <param name="str"></param>
/// <param name="pattern"></param>
/// <returns></returns>
public static int indexKMP(this string str, string pattern)
{
int i = 0;
int j = 0;
int[] nextVal = GetNextVal(pattern);
while (i<str.Length && j<pattern.Length)
{
if (j == -1 || str[i] == pattern[j])
{
i++;
j++;
}
else
{
j = nextVal[j];
}
}
if (j > pattern.Length - 1)
{
return i - pattern.Length;
}
else
{
return -1;
}
}
private static int[] GetNextVal(string pattern)
{
int j = 0, k = -1;
int[] nextVal = new int[pattern.Length];
nextVal[0] = -1;
while (j < pattern.Length - 1)
{
if (k == -1 || pattern[j] == pattern[k])
{
j++;
k++;
if (pattern[j] != pattern[k])
{
nextVal[j] = k;
}
else
{
nextVal[j] = nextVal[k];
}
}
else
{
k = nextVal[k];
}
}
return nextVal;
}
}
using System;
class KMPClass
{
static void Main(string[] args)
{
string mother = "concatenation";
string child = "cat";
int k = mother.indexKMP(child);
Console.WriteLine(k);
Console.Read();
}
}
public static class MyClass
{
/**//// <summary>
/// 简单版本,效率低
/// </summary>
/// <param name="str"></param>
/// <param name="child"></param>
/// <returns></returns>
public static int index(this string str,string child)
{
int i = 0;
int j = 0;
while (i < str.Length && j < child.Length )
{
if (str[i] == child[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j >child.Length - 1)
{
return i - child.Length;
}
else
{
return -1;
}
}
/**//// <summary>
/// KMP算法
/// </summary>
/// <param name="str"></param>
/// <param name="pattern"></param>
/// <returns></returns>
public static int indexKMP(this string str, string pattern)
{
int i = 0;
int j = 0;
int[] nextVal = GetNextVal(pattern);
while (i<str.Length && j<pattern.Length)
{
if (j == -1 || str[i] == pattern[j])
{
i++;
j++;
}
else
{
j = nextVal[j];
}
}
if (j > pattern.Length - 1)
{
return i - pattern.Length;
}
else
{
return -1;
}
}
private static int[] GetNextVal(string pattern)
{
int j = 0, k = -1;
int[] nextVal = new int[pattern.Length];
nextVal[0] = -1;
while (j < pattern.Length - 1)
{
if (k == -1 || pattern[j] == pattern[k])
{
j++;
k++;
if (pattern[j] != pattern[k])
{
nextVal[j] = k;
}
else
{
nextVal[j] = nextVal[k];
}
}
else
{
k = nextVal[k];
}
}
return nextVal;
}
}
2009年2月8日