Boyer-Moore算法

Boyer-Moore算法是一种在长字符串中查找子串的高效算法。它利用坏字符规则和好后缀规则来减少不必要的比较,提高查找效率。在匹配过程中,当遇到坏字符时,算法会根据子串中坏字符的位置来决定移动的距离;若遇到好后缀,则依据好后缀的规则计算移动位置。通过这两个规则,算法能在大多数情况下快速定位到可能的匹配位置,从而加速搜索过程。

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

作用:就是在一个长字符串中找有没有这个子串的算法
基本思路:从子串的最后一个字符开始对比
在这里插入图片描述
先将t跟s进行比较,不匹配,s就叫做坏字符,直接移动4个位置 在这里插入图片描述
将t跟t进行比较,匹配,再将x跟a进行比较,不匹配
t就叫做“好后缀”,而a就叫做坏字符,将其移动
坏字符的当前位置-坏字符在子串中出现的位置个字符(我是以1开始算字符串的长度的,比较好记)但是你写代码时记得把我写的数字都减一个1,因为下标是以0开始
如果坏字符不在子串中就将其当成0来算
这里也就是移动3-0=3个位置 在这里插入图片描述
将t与x进行比较,不匹配,x是坏字符,将其移动4-3=1个位置 在这里插入图片描述
这时你会发现如果你用坏字符的公式得出的结果为-1,难道你还要退回去走不行,所以这时你就需要用到另一个公式
后移位数 = 好后缀的位置 (以”好后缀”的最后一个字符为准)– 模式串中的上一次出现位置(如果”好后缀”在模式串中没有重复出现,则它的上一次出现位置为0,否则为1)
在这两个公式里面比较出较大的那个,将其作为后移的位数
像这里,这时你需要走的位数为4-1=3位
在这里插入图片描述
继续从后一位开始比,匹配成功则程序结束。

#include<stdio.h>
#include<string.h>
int main()
{
 char ss[]="thisisateexttext",s[]="text";
 int i,j=strlen(s)-1,k,l,f,m,n,a;
 for(i=j;i<strlen(ss);i+=l)
 {
  printf("%d   ",i);
  a=0;//用来记从后往前走了多少位才到坏字符的位置 
  l=0;//标记每次需往后移动多少位 
  m=f=i;n=j;//子串的最后一位和母串的最后一位的下标
  //m用来标记好后缀的最后一个字符 
  while(ss[f]==s[n])
    {
        if(n==0)
     break; 
     n--,f--;a++; 
    }
  if(n==0&&ss[f]==s[n])
    break;//一旦子串到了第一个的位置
    //并且与母串第一个字符相等就退出循环
    //否则就通过坏字符公式和好后缀公式来算移动位置 
  else
  {
   n=0;//用来判断在母串有没有重复的好后缀 
   for(k=0;k<=j;k++)
   {
    if(ss[f]==s[k])
    {
     l=(j-a)-k;//坏字符公式 
    }
    if(f!=m)
    {
        if(ss[m]==s[k])
        {
         n++; //判断好后缀有没有重复出现 
        } 
    }
   }
   if(!l)//如果坏字符在子串中没有出现的情况 
   {
    l=(j-a)+1;
   }
   if(n<2&&n>0)
   {
    m=strlen(s)+1; //如果重复出现,m就是子串的长度,否则+1 
   }
   else
     m=strlen(s);   
   if(m>l)
     l=m;//比较两者 
  }
  
 }
 printf("\n%d   ",i);
 return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值