求一份BM算法的C#代码实现 本帖最后由 Greyson_Xu 于 2011-10-17 14:29:42 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 一般比较少人专门写这个,网上很多c的BM算法,你改一下就行,不懂转的代码再在这问。http://hi.baidu.com/sicceer/blog/item/2c7d173ffe238ce754e723d1.html http://www.iteye.com/topic/353137可不可以按照这份C语言的代码帮我转下试试啊,我觉得这份写的比较清晰 我自己转了下,发现有点bug,注释在代码里面,各位看一下using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { loop: Console.WriteLine("输入文本字符串:"); string a=Console.ReadLine(); int s=a.Length; Console.WriteLine("输入模板:"); string b=Console.ReadLine(); int plen = b.Length; int[]skip= MakeSkip(b, plen); int[] shift = MakeShift(b, plen); int i = BMSearch(a, s, b, plen, skip, shift); Console.WriteLine(i); goto loop; } static int[] MakeSkip(string ptrn, int plen) { int a=0; int[] skip = new int[256]; for (int i = 0; i < 256; i++) { skip[i] = plen; } while(plen!=0) { skip[ptrn[a++]] = plen--; } return skip; } static int[] MakeShift(string ptrn, int plen) { int[] shift = new int[plen]; int pptr=plen-1; int sptr=plen - 1; char c; c = ptrn[plen - 1]; shift[sptr]=1; //pptr--; while (sptr-- != 0) { int p1=plen-2,p2,p3; do{ while(p1>=0&&ptrn[p1--]!=c); p2=plen-2; p3=p1; while(p3>0&&ptrn[p3--]==ptrn[p2--]&&p2>=pptr); }while(p3>=0&&p2>=pptr); shift[sptr]=plen-sptr+p2-p3; pptr--; } return shift; } //bug:当匹配模板只有一个字符,并且与文本的第一个字符不匹配时出现bug;待修改。 static int BMSearch(string buf, int blen, string ptrn, int plen, int[] skip, int[] shift) { int b_idx = plen; if (plen == 0) return 1; while (b_idx <= blen) { int p_idx = plen, skip_stride, shift_stride; while (buf[--b_idx] == ptrn[--p_idx]) { if (b_idx < 0) return 0; if (p_idx == 0) { return 1; } } skip_stride = skip[buf[b_idx]]; shift_stride = shift[p_idx]; b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride; } return 0; } }} 顶一下,bug在哪呢?C转C#要注意一些变量的长度不一样的问题,编码格式等等 //bug:当匹配模板只有一个字符,并且与文本的第一个字符不匹配时出现bug;待修改。 居然跑到我空间里去留言,你怎么找到我的?下面的代码暂时只支持ASCII字符 static int BmSerach(byte[] source, byte[] template) { // Prepare BmBc int[] bmBc = new int[256]; for(int i = 0; i < bmBc.Length; ++i) bmBc[i] = template.Length; for(int i = 0; i < template.Length - 1; ++i) bmBc[template[i]] = template.Length - 1 - i; // Prepare Suffix int[] suff = new int[template.Length]; suff[suff.Length - 1] = template.Length; for(int i = template.Length - 2; i >= 0; --i) { int q = i; while(q >= 0 && template[q] == template[template.Length - 1 - (i - q)]) --q; suff[i] = i - q; } // Prepare BmGs int[] bmGs = new int[template.Length]; for(int i = 0; i < bmGs.Length - 1; i++) bmGs[i] = template.Length; int j = 0; for(int i = template.Length - 1; i >= 0; --i) if(suff[i] == i + 1) for(; j < template.Length - 1 - i; ++j) if(bmGs[j] == template.Length) bmGs[j] = template.Length - 1 - i; for(int i = 0; i <= template.Length - 2; ++i) bmGs[template.Length - 1 - suff[i]] = template.Length - 1 - i; bmGs.ToList().ForEach(x => Console.Write(x.ToString() + ' ')); Trace.WriteLine(""); // Search j = 0; while(j < source.Length - template.Length) { int i = template.Length - 1; for(; i >= 0 && template[i] == source[j + i]; i--) ; if(i < 0) return j; else { int step = Math.Max(bmBc[source[j + i]], bmGs[i]); j += step; Console.WriteLine("STEP:" + j); } } return -1; } static void Main(string[] args) { loop: Console.WriteLine("输入文本字符串:"); string a = Console.ReadLine(); Console.WriteLine("输入模板:"); string b = Console.ReadLine(); int i = BmSerach(Encoding.ASCII.GetBytes(a), Encoding.ASCII.GetBytes(b)); Console.WriteLine(i); goto loop; } 呵呵,你回的有点晚了啊,我刚刚结晚贴…………srry!一般来留言的都有分,人少么就多拿,如果都不是好的答案,又分配不均匀么,则前楼多拿。我性子比较急啊……还以为你不看留言的。。还有什么补救措施不 彩票软件 自己定义的类使用窗口的控件问题。(不好意思,刚刚没有给出分数) 急 vs2003 怎么把 panel变成下拉式的容器呀 windowapplication中怎样改变启动窗口? 如何做出象验证码那样的背景框???? 接口还是继承? 如何使用资源文件 我该选择哪种数据库呢?请大家帮忙。 nhibernate的时候出现的错误,请哪位高手赐教 如何制作MSI呢? sqlcommand查询多个值赋值给多个变量 关于C#socket的问题
http://hi.baidu.com/sicceer/blog/item/2c7d173ffe238ce754e723d1.html
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
loop:
Console.WriteLine("输入文本字符串:");
string a=Console.ReadLine();
int s=a.Length;
Console.WriteLine("输入模板:");
string b=Console.ReadLine();
int plen = b.Length;
int[]skip= MakeSkip(b, plen);
int[] shift = MakeShift(b, plen);
int i = BMSearch(a, s, b, plen, skip, shift);
Console.WriteLine(i);
goto loop;
}
static int[] MakeSkip(string ptrn, int plen)
{
int a=0;
int[] skip = new int[256];
for (int i = 0; i < 256; i++)
{
skip[i] = plen;
}
while(plen!=0)
{
skip[ptrn[a++]] = plen--;
}
return skip;
} static int[] MakeShift(string ptrn, int plen)
{
int[] shift = new int[plen];
int pptr=plen-1;
int sptr=plen - 1;
char c;
c = ptrn[plen - 1];
shift[sptr]=1;
//pptr--;
while (sptr-- != 0)
{
int p1=plen-2,p2,p3;
do{
while(p1>=0&&ptrn[p1--]!=c); p2=plen-2;
p3=p1; while(p3>0&&ptrn[p3--]==ptrn[p2--]&&p2>=pptr); }while(p3>=0&&p2>=pptr); shift[sptr]=plen-sptr+p2-p3;
pptr--;
}
return shift;
}
//bug:当匹配模板只有一个字符,并且与文本的第一个字符不匹配时出现bug;待修改。
static int BMSearch(string buf, int blen, string ptrn, int plen, int[] skip, int[] shift)
{
int b_idx = plen;
if (plen == 0)
return 1;
while (b_idx <= blen)
{
int p_idx = plen, skip_stride, shift_stride;
while (buf[--b_idx] == ptrn[--p_idx])
{
if (b_idx < 0)
return 0;
if (p_idx == 0)
{
return 1;
}
}
skip_stride = skip[buf[b_idx]];
shift_stride = shift[p_idx];
b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
}
return 0;
} }
}
C转C#要注意一些变量的长度不一样的问题,编码格式等等
// Prepare BmBc
int[] bmBc = new int[256];
for(int i = 0; i < bmBc.Length; ++i)
bmBc[i] = template.Length;
for(int i = 0; i < template.Length - 1; ++i)
bmBc[template[i]] = template.Length - 1 - i; // Prepare Suffix
int[] suff = new int[template.Length];
suff[suff.Length - 1] = template.Length;
for(int i = template.Length - 2; i >= 0; --i) {
int q = i;
while(q >= 0 && template[q] == template[template.Length - 1 - (i - q)])
--q;
suff[i] = i - q;
} // Prepare BmGs
int[] bmGs = new int[template.Length];
for(int i = 0; i < bmGs.Length - 1; i++)
bmGs[i] = template.Length;
int j = 0;
for(int i = template.Length - 1; i >= 0; --i)
if(suff[i] == i + 1)
for(; j < template.Length - 1 - i; ++j)
if(bmGs[j] == template.Length)
bmGs[j] = template.Length - 1 - i;
for(int i = 0; i <= template.Length - 2; ++i)
bmGs[template.Length - 1 - suff[i]] = template.Length - 1 - i;
bmGs.ToList().ForEach(x => Console.Write(x.ToString() + ' '));
Trace.WriteLine(""); // Search
j = 0;
while(j < source.Length - template.Length) {
int i = template.Length - 1;
for(; i >= 0 && template[i] == source[j + i]; i--) ;
if(i < 0)
return j;
else {
int step = Math.Max(bmBc[source[j + i]], bmGs[i]);
j += step;
Console.WriteLine("STEP:" + j);
}
}
return -1;
} static void Main(string[] args) {
loop:
Console.WriteLine("输入文本字符串:");
string a = Console.ReadLine();
Console.WriteLine("输入模板:");
string b = Console.ReadLine();
int i = BmSerach(Encoding.ASCII.GetBytes(a), Encoding.ASCII.GetBytes(b));
Console.WriteLine(i);
goto loop;
}