C#实现字符串匹配算法

本文介绍了在C#中实现几种经典的字符串匹配算法,包括BF算法和MP算法。BF算法通过逐个字符比较实现匹配,当匹配失败时,主串回溯。MP算法则优化了BF算法,避免主串回溯,只利用模式串的回溯进行匹配。详细阐述了两种算法的工作原理,并给出了C#代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学习算法。刚学习完字符串匹配的几种算法: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)

当j=0时,代表第一个字符就匹配失败,规定此时n为-1;
当j=1时,代表第二个字符匹配失败。此时n为0;
当j=2时,则是在aba处匹配失败,前面并不能找到合格的n。则n为0;
当j=3时,则是在abab处匹配失败,则首字母a与j-1处的a是匹配的,则此时n为1;
当j=4时,则是在ababc处匹配失败,则前缀ab,与j-2~j-1处ab匹配,则此时n为2;
......
我们发现,j处的n值与j-1处的n值有关。
推理如下:
假设j-1处匹配失败,值为n,意思是:s2[0~n-1]=s2[j-1-n~j-2]。
若在j处匹配失败,有两种情况:
情况1:s2[j-1]=s2[n],那么s2[0~n]=s2[j-1-n~j-1],此时可得到j处匹配失败的n值为n+1;
情况2:s2[j-1]!=s2[n]。那么说明匹配成功的前缀字符一定不是n+1,但是会不会有更小的前缀字符匹配成功。
已经知道在j-1处的值为n,说明匹配成功的前缀字符为n,那么s2[n]处的匹配成功的前缀字符m,必定也是j-1处的匹配成功的前缀
s2[j-1]=s2[m],那么j处匹配失败的n值为m+1。否则n的值就依次循环到字符开始。
......
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值