前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >字符串匹配:字符串中查找某子串

字符串匹配:字符串中查找某子串

作者头像
跋扈洋
发布2022-03-29 08:53:44
1.4K0
发布2022-03-29 08:53:44
举报
文章被收录于专栏:物联网知识

需求

我们在平时的软件开发,尤其是嵌入式开发,字符串匹配是非常重要的一个算法。而目前常用的字符串匹配算法有很多,下面就来介绍几个。

具体算法

常规方法

对于字符串存放在字符数组的定长顺序存储结构中,可以利用计数指针指示主串和模式串当前正在比较的字符位置。算法的基本思路是:从主串的第i个字符起和模式串的第一个字符比较。若相等,则继续比较后续字符;否则从主串的下一个字符起再重新和模式串的第一个开始比。知道模式串被比较完成,代表主串中存在模式串。

程序

代码语言:javascript
复制
int index(string S,stringT,int pos)
{
    int i,j;
    i=pos;
    j=1;
    while(i<=S[0]&&j<=T[0])
    {
        if(S[i]==T[j])
        {
            ++i;
            j++;
        }
        else
        {
            i=i-j+2;
            j=1;
        }
    }
    if(j>T[0])
    return i-T[0];
    else return 0;

}

KMP算法

KMP算法又称为克努特—莫里斯—普拉特操作,是一种效率非常高的字符串匹配算法。KMP算法是一种改进的字符串匹配算法,其关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。此算法可以在O(n+m)的时间数量级上完成串的模式匹配操作。其算法的思路在于:每当一趟匹配过程中出现字符比较不等时,不需要回溯指针,而是利用已经得到的“部分匹配”的结果将模式向右“滚动”尽可能远的一段距离后,继续进行比较。

我们首先要明确一个概念,字符串最长前-后缀。

举例,字符串 abcdab

前缀的集合:{a,ab,abc,abcd,abcda}

后缀的集合:{b,ab,dab,cdab,bcdab}

那么最长前-后缀就是ab。

而KMP算法将最长前-后缀概念用在了next数组上。

next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。例如如果next [j] = k,代表j 之前的字符串中有最大长度为k 的相同前缀后缀。

这就意味着在某个字符失配时,该字符对应的next 值会告诉你下一步匹配中,模式串应该跳到哪个位置(跳到next [j] 的位置)。如果next [j] 等于0或-1,则跳到模式串的开头字符,若next [j] = k 且 k > 0,代表下次匹配跳到j 之前的某个字符,而不是跳到开头,且具体跳过了k 个字符。

程序

首先我们需要求next数组

代码语言:javascript
复制
typedef struct
{  
  char data[MaxSize];
  int length;      //串长
} SqString;
void GetNext(SqString t,int next[])    //由模式串t求出next值
{
  int i,k;
  i=0;k=-1;
  next[0]=-1;//第一个字符前无字符串,给值-1
  while (i<t.length-1) 
  {  
    if (k==-1 || t.data[i]==t.data[k])   //k为-1或比较的字符相等时
    {  
      i++;k++;
      next[i]=k;
         }
         else
    {
      k=next[k];
    }
  }
}

KPM算法

代码语言:javascript
复制
int KMPIndex(SqString s,SqString t)  
{

  int next[MaxSize],i=0,j=0;
  GetNext(t,next);
  while (i<s.length && j<t.length) 
  {
    if (j==-1 || s.data[i]==t.data[j]) 
    {
      i++;j++;        //i,j各增1
    }
    else j=next[j];     
    }
    if (j>=t.length)
    return(i-t.length);    //返回匹配模式串的首字符下标
    else  
    return(-1);            //返回不匹配标志
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 物联网知识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档