字符串匹配(蛮力法+KMP)

1. 问题描述:

给定一个文本串和一个模式串,查找模式串是否为文本串的连续子串,如果是,则返回文本串的第一个匹配子串中第一个字符的位置。(这个问题应用十分广泛,所有查询问题的实质都是类似于字符串匹配,匹配成功则表示文本中含有这句话)

2. 题解

(1)蛮力法

在这里插入图片描述
上图为字符串匹配问题的示意图,文本串T与模式串P,我们的目标是查找模式串P是否为文本串的连续子串。在学习算法之前,首先想到的肯定是蛮力法,也就是使用最暴力的方法解决问题(蛮力法一般是最容易想到的方法,但是也几乎是效率最低的),下面一起来看一下蛮力法的实现过程:
首先应该明确一点,如果以T[n-m]为首字符的文本串还是无法与模式串匹配,则必定匹配失败。我们的方法是从0 ~ n-m遍历每个字符,分别以该字符为首字符依次比较文本串与模式串,相等则继续向右比较直到模式串没有字符了,如果不相等则将 i + 1,即说明以 i 为首字符的串不能匹配模式串。该算法的时间复杂度为O(m*n).

BruteForceStringMatch(T[0...n-1],P[0...m-1])
// 该算法实现了蛮力字符串匹配
// 输入:一个n个字符的数组T[0...n-1]代表一段文本串
        一个m个字符的数组P[0...n-1]代表一个模式串
// 输出:如果查找成功的话,返回文本串的第一个匹配字符串中第一个字符的位置,否则返回-1
for i ⬅ 0 to n - m do
     j ⬅ 0 
     while j < m and P[j] = T[i + j] do
          j ⬅ j + 1
     if j = m   return i
return -1

在这里插入图片描述

(2) KMP算法

虽然KMP算法并非现有字符串匹配问题的最佳算法,但是却是数据结构中必学的算法,如果完全没接触过的小伙伴可以先去了解一下KMP算法。
在这里插入图片描述
KMP算法最大的优点就是没有回溯。没有回溯的模式匹配算法:用 S[i]与T[]匹配,若相等则往后继续匹配,否则就用S[i与T[next[i]]匹配,直至匹配成功或失败为止。

int Index_KMP (SString S, SString T, int pos)  {
    
    
       i= pos, j =1;
       while (i<=S[0] && j<=T[0])
               if (j==0 || S[i]==T[j])  {
    
     
                    i++; j++; }
               else 
                    j=next[j];                     //i不变, j后退
       if (j>t[0])  return i-t[0];          //匹配成功
       else   return 0;                 //返回不匹配标志
}

猜你喜欢

转载自blog.csdn.net/m0_51339444/article/details/124274550