当前位置: 首页 > article >正文

串匹配问题的三种算法

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.kler.cn/a/322495.html

相关文章:

  • 京东 2025届秋招 自然语言处理
  • RabbitMQ的基本概念和入门
  • Django5 2024全栈开发指南(二):Django项目配置详解
  • sapiens推理的安装与使用
  • Docker: ubuntu系统下Docker的安装
  • 一体化运维监控管理平台:产品架构与功能解析
  • 卫星导航定位原理学习(三)
  • C语言malloc()函数与calloc()函数的区别
  • Unity 设计模式 之 行为型模式-【命令模式】【责任链模式】
  • 个人网站介绍和部署(开源)
  • HTML和CSS做一个无脚本的手风琴页面(保姆级)
  • 打开ffmpeg编码器的时候报错:avcodec_open2()返回-22
  • 数据结构之“队列”
  • Comfyui 学习笔记1
  • Java设计模式——工厂模式扩展
  • 算法打卡:第十一章 图论part02
  • 2024年Oceanbase考试认证的习题以及注意事项
  • 基于SpringBoot+Vue+MySQL的医院信息管理系统
  • 系统架构笔记-2-计算机系统基础知识
  • 数据处理与统计分析篇-day11-RFM模型案例
  • CANopen开源库canfestival的移植
  • ARM单片机的内存分布(重要)
  • 碳性电池和碱性电池的区别
  • 【中级通信工程师】终端与业务(九):市场细分与选择
  • Spring Cloud Alibaba-(6)Spring Cloud Gateway【网关】
  • windows控制台ssh登录(ssh远程登录)(ssh连接ssh、直连ssh直连、cmd连接ssh)控制台连接ssh