串匹配问题的三种算法

news2024/9/27 21:29:33

BF算法

#include <iostream>  
#include <string>  
  
using namespace std;  
  
// 暴力匹配算法  
int bruteForceMatch(const string& s, const string& p) {  
    int n = s.length();  
    int m = p.length();  
    for (int i = 0; i <= n - m; ++i) {  
        int j;  
        for (j = 0; j < m; ++j) {  
            if (s[i + j] != p[j])  
                break;  
        }  
        if (j == m)  
            return i; // 匹配成功  
    }  
    return -1; // 匹配失败  
}  
  
int main() {  
    string s = "ABABDABACDABABCABAB";  
    string p = "ABABCABAB";  
    cout << "Brute-Force Match Result: " << bruteForceMatch(s, p) << endl;  
    return 0;  
}

KMP算法

#include <iostream>  
#include <string>  
#include <vector>  
  
using namespace std;  
  
// 计算部分匹配表  
vector<int> computeLPSArray(const string& p, int M) {  
    vector<int> lps(M, 0);  
    int len = 0;  
    int i = 1;  
    while (i < M) {  
        if (p[i] == p[len]) {  
            len++;  
            lps[i] = len;  
            i++;  
        } else { // (p[i] != p[len])  
            if (len != 0) {  
                len = lps[len - 1];  
            } else { // if (len == 0)  
                lps[i] = len;  
                i++;  
            }  
        }  
    }  
    return lps;  
}  
  
// KMP算法  
int KMPSearch(const string& s, const string& p) {  
    int n = s.length();  
    int m = p.length();  
    vector<int> lps = computeLPSArray(p, m);  
    int i = 0; // s的索引  
    int j = 0; // p的索引  
    while (i < n) {  
        if (p[j] == s[i]) {  
            j++;  
            i++;  
        }  
        if (j == m) {  
            return i - j; // 匹配成功,返回模式串在主串中的起始位置  
            j = lps[j - 1];  
        }  
        // 不匹配时  
        else if (i < n && p[j] != s[i]) {  
            // 不为0则回到之前某个位置  
            if (j != 0)  
                j = lps[j - 1];  
            else // j == 0  
                i = i + 1;  
        }  
    }  
    return -1; // 匹配失败  
}  
  
int main() {  
    string s = "ABABDABACDABABCABAB";  
    string p = "ABABCABAB";  
    cout << "KMP Match Result: " << KMPSearch(s, p) << endl;  
    return 0;  
}

BM算法

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class BoyerMoore {
public:
    BoyerMoore(const string& pattern) {
        this->pattern = pattern; // 存储模式串
        this->m = pattern.length(); // 模式串长度
        buildBadChar(); // 构建坏字符表
        buildGoodSuffix(); // 构建好后缀表
    }

    // 在文本中搜索模式串
    void search(const string& text) {
        int n = text.length(); // 文本长度
        int s = 0; // 当前文本的起始位置

        while (s <= n - m) { // 直到文本末尾
            int j = m - 1; // 从模式串末尾开始比较

            // 比较模式串与文本
            while (j >= 0 && pattern[j] == text[s + j]) {
                j--;
            }

            // 如果找到匹配
            if (j < 0) {
                cout << "Pattern found at index " << s << endl;
                // 移动模式串
                s += (s + m < n) ? m - badChar[text[s + m]] : 1;
            } else {
                // 移动模式串
                s += max(1, j - badChar[text[s + j]]);
            }
        }
    }

private:
    string pattern; // 模式串
    int m; // 模式串长度
    vector<int> badChar; // 坏字符表
    vector<int> goodSuffix; // 好后缀表

    // 构建坏字符表
    void buildBadChar() {
        badChar.assign(256, -1); // 初始化为-1
        for (int i = 0; i < m; i++) {
            badChar[(int)pattern[i]] = i; // 更新坏字符的位置
        }
    }

    // 构建好后缀表
    void buildGoodSuffix() {
        goodSuffix.assign(m + 1, m); // 初始化
        vector<int> z(m); // z数组
        int last = m - 1;

        for (int i = m - 1; i >= 0; i--) {
            if (i == last) {
                while (last >= 0 && pattern[last] == pattern[last - (m - 1 - i)]) {
                    last--;
                }
                goodSuffix[m - 1 - i] = last + 1; // 更新好后缀
            } else {
                goodSuffix[m - 1 - i] = last - i; // 更新
            }
        }
    }
};

int main() {
    string text = "ABAAABCDABCDE"; // 文本
    string pattern = "ABC"; // 模式串
    BoyerMoore bm(pattern); // 创建BM对象
    bm.search(text); // 搜索模式串
    return 0;
}
  1. 暴力匹配算法(BF算法):最坏情况时间复杂度:O(m * n),其中m是模式串长度,n是文本长度。最坏情况下,需要逐个字符比较。

  2. KMP算法:最坏情况时间复杂度:O(m + n)。KMP通过预处理模式串生成部分匹配表,避免了不必要的回溯,从而提高了效率。

  3. Boyer-Moore算法(BM算法):最坏情况时间复杂度:O(m * n),但在大多数实际情况中,平均时间复杂度是O(n/m)。BM算法通过坏字符和好后缀启发式规则有效减少比较次数,通常在长模式串和长文本中表现优越。

总结:

BF:简单但效率低,尤其在长文本和模式串时。

KMP:高效,适合任何情况。

BM:在实际应用中通常更快,尤其是长模式串时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2171119.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache OFBiz SSRF漏洞CVE-2024-45507分析

Apache OFBiz介绍 Apache OFBiz 是一个功能丰富的开源电子商务平台&#xff0c;包含完整的商业解决方案&#xff0c;适用于多种行业。它提供了一套全面的服务&#xff0c;包括客户关系管理&#xff08;CRM&#xff09;、企业资源规划&#xff08;ERP&#xff09;、订单管理、产…

Vulhub TheEther_1.0.1靶机详解

项目地址 https://download.vulnhub.com/theether/theEther_1.0.1.zip实验过程 将下载好的靶机导入到VMware中&#xff0c;设置网络模式为NAT模式&#xff0c;然后开启靶机虚拟机 使用nmap进行主机发现&#xff0c;获取靶机IP地址 nmap 192.168.47.1-254根据对比可知theEthe…

【 EXCEL 数据处理 】000003 案列 标记涨跌,保姆级教程。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来,方便查看。

【 EXCEL 数据处理 】000003 案列 使用条件格式之大于和小于&#xff0c;标记涨跌&#xff0c;保姆级教程。使用的软件是微软的Excel操作的。处理数据的目的是让数据更直观的显示出来&#xff0c;方便查看。 &#x1f4da;一、直接上案例 &#x1f4d6;1.使用条件格式之大于和小…

CMU 10423 Generative AI:lec7、8、9(专题2:一张图理解diffusion model结构、代码实现和效果)

本文介绍diffusion model是什么&#xff08;包括&#xff1a;模型详细的架构图、各模块原理和输入输出、训练算法解读、推理算法解读&#xff09;、以及全套demo代码和效果。至于为什么要这么设计、以及公式背后的数学原理&#xff0c;过程推导很长很长&#xff0c;可见参考资料…

Bug:ThreadPoolTaskScheduler搭配CronTask完成定时任务,关闭scheduler后CronTask任务仍然执行?

【问题】执行下面代码后&#xff0c;关闭ThreadPoolTaskScheduler&#xff0c;CronTask仍然继续执行。 Configuration public class config {Beanpublic String getString() throws InterruptedException {Runnable runnable () -> {try {System.out.println("hello r…

动态规划算法:13.简单多状态 dp 问题_打家劫舍II_C++

目录 题目链接&#xff1a;LCR 090. 打家劫舍 II - 力扣&#xff08;LeetCode&#xff09; 一、题目解析 题目&#xff1a; 解析&#xff1a; 二、算法原理 1、状态表示 2、状态转移方程 状态转移方程推理&#xff1a; 1、i位置状态分析 2、首尾状态分析 3、初始化 d…

Meta震撼发布Llama3.2大规模模型

在2024.9.26的年Meta Connect大会上&#xff0c;Meta正式推出了Llama3.2模型&#xff0c;旨在提升边缘AI和视觉任务的能力。Llama3.2系列包括11亿和90亿参数的中型视觉模型&#xff0c;以及为移动设备优化的1亿和3亿参数的小型模型&#xff0c;并针对高通和联发科的硬件平台进行…

Webpack 介绍

Webpack 介绍 Date: August 29, 2024 全文概要 Webpack概念&#xff1a; Webpack是一个静态的模块化的打包工具&#xff0c;可以为现代的 JavaSript 应用程序进行打包。 1-静态&#xff1a;Webpack可以将代码打包成最终的静态资源 2-模块化&#xff1a;webpack支持各种模块…

教师工作量评估与管理软件

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

Spring异常处理-@ExceptionHandler-@ControllerAdvice-全局异常处理

文章目录 ResponseBodyControllerAdvice最终的异常处理方式 异常的处理分两类 编程式处理&#xff1a;也就是我们的try-catch 声明式处理&#xff1a;使用注解处理 ResponseBody /*** 测试声明式异常处理*/ RestController public class HelloController {//编程式的异常处理&a…

EasyAR自定义相机RTSP视频流(CustomCamera)

EasyAR可以使用视频源作为输入源&#xff0c;官方给出了示例和文档&#xff0c;但是对于大部分Unity开发人员来说看了文档还是一头雾水。 在Android Studio中将custom-camera.jar添加libs中&#xff0c;就可以查看源代码了 分析其源代码&#xff0c;主要是ExternalCameraSampl…

【linux 多进程并发】linux下使用常见命令,来解析进程家族体系脉络

0101 Linux进程 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章目录 0101 Li…

ASP.NET Core 打包net8.0框架在Linux CentOS7上部署问题

问题1 libstdc.so.6版本过低。 CentOS7默认安装的gcc版本太低&#xff0c;达不到.net8的启动条件。 /lib64/libstdc.so.6: version GLIBCXX_3.4.20’ not found (required by ./IDT_net) /lib64/libstdc.so.6: version GLIBCXX_3.4.21’ not found (required by ./IDT_net) 解…

恢复丢失的数据:恢复数据库网络解决方案

探索恢复数据库网络的深度对于了解现代企业如何防御其数据不断增长的威胁至关重要。在一个时代&#xff0c;数字证据和取证网络安全在法律和商业领域扮演关键角色&#xff0c;这些网络提供的弹性是不可或缺的。深入研究恢复数据库网络的重要性不仅仅是数据保护&#xff0c;它还…

ubuntu安装mysql 8,mysql密码的修改

目录 1.安装mysql 82.查看当前状态3.手动给数据库设置密码mysql5mysql8 4.直接把数据库验证密码的功能关闭掉 1.安装mysql 8 apt install mysql-server-8.0敲 Y 按回车 table 选ok 2.查看当前状态 service mysql status显示active&#xff08;running&#xff09;证明安装成…

媒界:吉利星瑞百炼成钢,持续引领中国汽车价值向上

秋风送爽绘秋色&#xff0c;出行良辰恰逢时。9月28日至9月29日&#xff0c;2024安行中国汽车安全科技公益巡展迎来尾声&#xff0c;安行中国携手吉利汽车&#xff0c;步履轻盈地踏入苏州星湖天街&#xff0c;共同呈献一场融合环保科技前沿、安全驾驶理念与深厚文化底蕴的48小时…

使用jQuery处理Ajax

使用jQuery处理Ajax HTTP协议 超文本传输协议&#xff08;HTTP&#xff0c;HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议 设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法 所有的WWW文件都必须遵守这个标准 一次HTTP操作称为一个事务&am…

如何使用 CCF Communicator 框架快速开发设备接口

什么是 CCF Communicator Framework&#xff1f; 通信器框架通过封装 CCF 和设备之间的连接&#xff0c;简化了硬件之间的低级消息处理。 举例来说&#xff0c;考虑一下控制软件和硬件设备之间的连接方式。ASCII 串行连接需要使用 TCP 的套接字连接、用于处理设备发送/接收的…

肺癌类器官培养研究概述

前 言 2023年是类器官被《Science》杂志评为年度十大技术的10周年。10年后类器官技术发展迅猛&#xff0c;犹如一颗璀璨的明珠&#xff0c;不断的为生命科学研究揭示新的奥秘&#xff0c;推动生物医学领域不断前行。肺类器官培养条件也在不断完善&#xff0c;在基础和临床研究…

MySQL面试知识汇总

学习链接 创建索引有哪些注意点&#xff1f; 索引应该建在查询频繁的字段&#xff0c;比如where查询、order排序索引的个数应该适量&#xff08;最多64个&#xff09;&#xff0c;索引需要占用空间&#xff0c;更新时也需要维护区分度低的字段&#xff0c;例如性别&#xff0c…