前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >模式搜索简介-数据结构和算法教程

模式搜索简介-数据结构和算法教程

作者头像
用户1418987
发布2024-01-30 08:16:06
820
发布2024-01-30 08:16:06
举报
文章被收录于专栏:codercoder

模式搜索简介 - 数据结构和算法教程

模式搜索是一种涉及搜索字符串、单词、图像等模式的算法。

我们使用某些算法来进行搜索过程。模式搜索的复杂性因算法而异。在数据库中执行搜索时它们非常有用。模式搜索算法对于在较大字符串的子字符串中查找模式非常有用。这个过程可以使用我们将在本文章中讨论的各种算法来完成。

模式搜索算法的特点:

  • 模式搜索算法应该快速准确地识别熟悉的模式。
  • 识别并分类不熟悉的模式。
  • 即使部分隐藏,也能识别模式。
  • 轻松、自动地快速识别模式。

朴素模式搜索算法

朴素模式搜索是其他模式搜索算法中最简单的方法。它检查模式中主字符串的所有字符。该算法对于较小的文本很有帮助。它不需要任何预处理阶段。我们可以通过检查一次字符串来找到子字符串。它也不占用额外的空间来执行操作。

模式搜索简介-数据结构和算法教程_字符串
模式搜索简介-数据结构和算法教程_字符串

朴素模式搜索方法的时间复杂度为 O(m*n)。m 是模式的大小,n 是主字符串的大小。

代码语言:javascript
复制
// Naive Pattern 的 JS 程序
 // 搜索算法
 function search(pat, txt) 
 { 
     let M = pat.length; 
     let N = txt.length; 
     
     /* 逐个滑动 pat[] 的循环 */
     for (let i = 0; i <= N - M; i++) { 
         let j = 0; 
         
         /* 对于当前索引 i,检查是否匹配模式 */
         for (j = 0; j < M; j++) {
             if (txt[i + j] != pat[j]) {
         break; 
       }
         }   
         if (j == M) {// if pat[0...M-1] = txt[i, i+1, ...i+M-1] 
             console.log("Pattern found at index",i); 
     }
     } 
 } 
 
 let txt = "AABAACAADAABAAABAA"; 
 let pat = "AABA"; 
 search(pat, txt);

输出:

代码语言:javascript
复制
在索引 0 处找到模式
 在索引 9 处找到模式
 在索引 13 处找到模式

时间复杂度: O(N*M) 辅助空间: O(1)

KMP算法

KMP算法用于在“文本”中查找“模式”。该算法从左到右逐个字符进行比较。但每当发生不匹配时,它都会使用一个名为“前缀表”的预处理表来跳过匹配时的字符比较。有时前缀表也称为LPS表。这里 LPS 代表“最长的正确前缀,也是后缀”。

如何使用 LPS 表

我们使用LPS表来决定当发生不匹配时要跳过多少个字符进行比较。 当发生不匹配时,检查模式中不匹配字符的前一个字符的 LPS 值。如果为“0”,则开始将模式的第一个字符与下一个字符与文本中不匹配的字符进行比较。如果它不是“0”,则开始将索引值等于前一个字符的LPS值的字符与模式中的不匹配字符与文本中的不匹配字符进行比较。

模式搜索简介-数据结构和算法教程_搜索算法_02
模式搜索简介-数据结构和算法教程_搜索算法_02

KMP算法示例

模式搜索简介-数据结构和算法教程_字符串_03
模式搜索简介-数据结构和算法教程_字符串_03

从左到右比较模式的第一个字符与文本的第一个字符

模式搜索简介-数据结构和算法教程_搜索算法_04
模式搜索简介-数据结构和算法教程_搜索算法_04

将模式的第一个字符与文本的下一个字符进行比较

比较模式[0]和模式[1]值

将模式[0] 与文本中的下一个字符进行比较。

模式搜索简介-数据结构和算法教程_搜索算法_05
模式搜索简介-数据结构和算法教程_搜索算法_05

将模式[2] 与文本中不匹配的字符进行比较。

KMP 算法的工作原理

让我们看一下 KMP 算法在文本中查找模式的工作示例。

模式搜索简介-数据结构和算法教程_搜索算法_06
模式搜索简介-数据结构和算法教程_搜索算法_06

脂多糖表

定义变量

模式搜索简介-数据结构和算法教程_字符串_07
模式搜索简介-数据结构和算法教程_字符串_07

比较 A 和 B

模式搜索简介-数据结构和算法教程_模式搜索_08
模式搜索简介-数据结构和算法教程_模式搜索_08

比较 A 和 C

模式搜索简介-数据结构和算法教程_模式搜索_09
模式搜索简介-数据结构和算法教程_模式搜索_09

比较 A 和 D

模式搜索简介-数据结构和算法教程_模式搜索_10
模式搜索简介-数据结构和算法教程_模式搜索_10

比较 A 与 A

模式搜索简介-数据结构和算法教程_搜索算法_11
模式搜索简介-数据结构和算法教程_搜索算法_11

将 B 与 B 进行比较

模式搜索简介-数据结构和算法教程_搜索算法_12
模式搜索简介-数据结构和算法教程_搜索算法_12

比较 C 和 D

模式搜索简介-数据结构和算法教程_模式搜索_13
模式搜索简介-数据结构和算法教程_模式搜索_13

比较 A 和 D

KMP算法的实现:

JavaScript

代码语言:javascript
复制
// 在 pat[] 中出现 txt[] 的次数
 function computeLPSArray(pat, M, lps) 
 { 
 
     // 前一个最长前缀后缀的长度
     let len = 0; 
     lps[0] = 0; 
     // 循环计算 lps[i],其中 i 的取值范围为 1 到 M-1
     let i = 1; 
     while (i < M) { 
         if (pat[i] == pat[len]) { 
             len++; 
             lps[i] = len; 
             i++; 
         } 
         else // (pat[i] != pat[len]) 
         { 
         
             // This is tricky. Consider the example. 
             // AAACAAAA and i = 7. The idea is similar 
             // to search step. 
             if (len != 0) { 
                 len = lps[len - 1]; 
                 // 另外,请注意我们在这里不递增 i
             } 
             else // if (len == 0) 
             { 
                 lps[i] = 0; 
                 i++; 
             } 
         } 
     } 
 } 
 function KMPSearch(pat, txt) { 
     let M = pat.length; 
     let N = txt.length 
     
     // 创建一个lps[]数组,用于存储模式的最长前缀后缀值
     let lps = []; 
     
     // Preprocess the pattern (calculate lps[] array) 
     computeLPSArray(pat, M, lps); 
     let i = 0; // index for txt[] 
     let j = 0; // index for pat[] 
     while ((N - i) >= (M - j)) { 
         if (pat[j] == txt[i]) { 
             j++; 
             i++; 
         } 
         if (j == M) { 
             console.log("Found pattern at index:", i - j); 
             j = lps[j - 1]; 
         } 
         
         // mismatch after j matches 
         else if (i < N && pat[j] != txt[i]) 
         { 
         
             // 不要匹配 lps[0..lps[j-1]] 个字符,
             // 它们无论如何都会匹配
             if (j != 0) {
         j = lps[j - 1]; 
       } else {
         i = i + 1; 
       }
         } 
     } 
 } 
 
 // 为给定的模式pat[0..M-1]填充lps[]
 // 测试上述函数的驱动程序
 let txt = "ABABDABACDABABCABAB"; 
 let pat = "ABABCABAB"; 
 KMPSearch(pat, txt);

输出

代码语言:javascript
复制
在索引 10 处找到模式

时间复杂度: O(n + m) 辅助空间: O(M)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模式搜索简介 - 数据结构和算法教程
  • 模式搜索算法的特点:
  • 朴素模式搜索算法
  • KMP算法
    • 如何使用 LPS 表
      • KMP 算法的工作原理
        • JavaScript
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档