这里直接贴上代码
对这个算法原理不太熟悉的同志可以看下这个,说的比较好:
阮一峰-字符串匹配的Boyer-Moore算法
因为本人是新手,自己直接用代码实现不了,所以这是根据别人用c++写的算法直接改的,不过这里让算法可以匹配中文,我在其他博客上查的好像都不行。
引用源码地址:字符串匹配算法(BM)上面有代码说明。
c#代码
初始化部分:
public static int[] nums//在主程序生成hash表,然后每次调用直接值拷贝,可以不用每次调用重新生成
{
get
{
int[] arr = new int[100000];//这里直接设置100000,可以支持中文范围
for (int i = 0; i < 100000; i++)
{
arr[i] = -1;
}
return arr;
}
}
算法实现部分:
public static class BMAlgorithm
{
static void generateBadChar(char[] b, int m, int[] badchar, int[] num)
{
int i, ascii;
badchar = num;
for (i = 0; i < m; ++i)
{
ascii = (int) b[i];
badchar[ascii] = i;
}
}
static void generateGS(char[] b, int m, int[] suffix, bool[] prefix)
{
int i, j, k;
for (i = 0; i < m; ++i)
{
suffix[i] = -1;
prefix[i] = false;
}
for (i = 0; i < m - 1; ++i)
{
j = i;
k = 0;
while (j >= 0 && b[j] == b[m - 1 - k])
{
--j;
++k;
suffix[k] = j + 1;
}
if (j == -1)
{
prefix[k] = true;
}
}
}
static int moveByGS(int j, int m, int[] suffix, bool[] prefix)
{
int k = m - 1 - j;
if (suffix[k] != -1)
{
return j - suffix[k] + 1;
}
for (int i = j + 2; i < m; ++i)
{
if (prefix[m - i] == true)
{
return i;
}
}
return m;
}
public static int str_bm(char[] a, int n, char[] b, int m, int[] num)
{
int[] badchar = num;
generateBadChar(b, m, badchar, num);
int[] suffix = new int[m];
bool[] prefix = new bool[m];
generateGS(b, m, suffix, prefix);
int i = 0, j, movelen1, movelen2;
while (i < n - m + 1)
{
for (j = m - 1; j >= 0; --j)
{
if (a[i + j] != b[j])
{
break;
}
}
if (j < 0)
{
return i;
}
movelen1 = j - badchar[(int) a[i + j]];
movelen2 = 0;
if (j < m - 1)
{
movelen2 = moveByGS(j, m, suffix, prefix);
}
i = i + (movelen2 > movelen1 ? movelen2 : movelen1);
}
return -1;
}
}
测试:
static void Main(string[] args)
{
char[] a = "abcsdsdadads".ToCharArray();
char[] b = "dsd".ToCharArray();
Console.WriteLine(BMAlgorithm.str_bm(a,a.Length,b,b.Length,nums));
char[] c = "你好吗".ToCharArray();
char[] d = "好".ToCharArray();
Console.WriteLine(BMAlgorithm.str_bm(c, c.Length, d,d.Length,nums));
}
结果:
文本字符查询程序
字符查询程序 可以同步查询文本。
因为水平有限,如果发现有什么问题还望请指正,谢谢。当然我测试时未发现问题,