首页 > 编程语言 >KMP算法

KMP算法

时间:2024-04-18 19:11:18浏览次数:25  
标签:匹配 int pattern 模式 next 算法 KMP

KMP算法

KMP算法的核心思想是利用模式串自身的特性,在匹配过程中尽量避免回溯,以提高匹配的效率。它通过构建一个部分匹配表(也称为next数组),来指导匹配过程中模式串的移动位置,从而减少不必要的字符比较。

KMP算法的基本步骤

  • 1.构建部分匹配表(next):遍历模式串,对于每个位置i,找出以位置i结尾的前缀子串和后缀子串的最长公共长度,并将该长度记录在next[i]中。
  • 2.匹配过程:在匹配过程中,使用两个指针i和j分别指向文本串和模式串。当字符匹配时,两个指针同时向后移动;当字符不匹配时,根据分配表,构建部分分配表,将模式串向右移动一定的距离,以减少不必要的比较
  • 当j移动到模式串的末尾时,表示匹配成功;否则匹配失败。
#include <stdio.h>
#include <string.h>

// 构建部分匹配表(next数组)
void buildNext(const char *pattern, int next[]) {
    int len = strlen(pattern); // 获取模式串的长度
    int i = 0, j = -1;
    next[0] = -1; // next[0]初始化为-1,表示不存在更短的相同前缀和后缀

    while (i < len - 1) {
        if (j == -1 || pattern[i] == pattern[j]) { // 如果j为-1(即已经移动到了模式串的开头)或者当前字符匹配
            ++i;
            ++j;
            next[i] = j; // 记录最长相同前缀和后缀的长度
        } else {
            j = next[j]; // 如果当前字符不匹配,根据部分匹配表调整j的位置
        }
    }
}

// KMP匹配算法
int kmp(const char *text, const char *pattern) {
    int lenText = strlen(text); // 获取文本串的长度
    int lenPattern = strlen(pattern); // 获取模式串的长度
    int next[lenPattern]; // 创建部分匹配表

    buildNext(pattern, next); // 构建部分匹配表

    int i = 0, j = 0;
    while (i < lenText && j < lenPattern) {
        if (j == -1 || text[i] == pattern[j]) { // 如果j为-1(即已经移动到了模式串的开头)或者当前字符匹配
            ++i;
            ++j;
        } else {
            j = next[j]; // 如果当前字符不匹配,根据部分匹配表调整j的位置
        }
    }

    if (j == lenPattern) { // 如果j等于模式串长度,说明匹配成功
        return i - j; // 返回匹配成功的起始位置
    } else {
        return -1; // 匹配失败
    }
}

int main() {
    const char *text = "BBC ABCDAB ABCDABCDABDE";
    const char *pattern = "ABCDABD";
    int result = kmp(text, pattern);
    if (result != -1) {
        printf("Pattern found at index %d\n", result);
    } else {
        printf("Pattern not found\n");
    }
    return 0;
}


标签:匹配,int,pattern,模式,next,算法,KMP
From: https://www.cnblogs.com/doubleconquer/p/18132856

相关文章

  • good-turning算法
    解答:合并验证集与训练集,计算合并之和的数据集在训练集中出现的次数:张三喜欢外出旅行李四登山王五不喜欢12211100那么:r012N(r)242根据公式计算可以得到:r*r(0)=2r(1)=1r(2)=2N(r*)242(最高次数的N(r*)不变的)那么......
  • 边缘计算智能分析网关V4地面垃圾AI检测算法介绍及场景应用
    在传统的卫生监管场景中,无法及时发现地面遗留的垃圾,通过人工巡逻的方式需要大量的人力、物力和时间,而且效率不高,并存在一定的滞后性,而采用地面垃圾AI检测算法则可以大大提高监管效率。TSINGSEE青犀AI智能分析网关V4的地面垃圾AI检测算法可以自动识别划定区域内遗留的垃圾,若达到设......
  • TSINGSEE青犀算法中台消防通道堵塞/占压AI检测算法的介绍及应用
    消防通道是建筑物内用于紧急疏散的通道,其畅通无阻对于保障人员生命安全至关重要。然而,由于各种原因,消防通道经常会被杂物、车辆等堵塞,一旦发生火灾等紧急情况,后果不堪设想。为了有效解决这一问题,我们提出了一种基于人工智能技术的消防通道堵塞占用检测算法。该算法利用深度学习技......
  • 30天【代码随想录算法训练营34期】第七章 回溯算法part06 (● 332.重新安排行程 ● 51
    332.重新安排行程木有看懂,没视频所以也没看懂51.N皇后自己写出来还是有难度的classSolution:defsolveNQueens(self,n:int)->List[List[str]]:result=[]#存储最终结果的二维字符串数组chessboard=['.'*nfor_inrange(n)]#初始化......
  • Dijkstra算法
    单源最短路算法,不能处理负环,朴素版时间复杂度\(O(n^2)\),堆优化版时间复杂度\(O(nlogn)\)。Dijkstra算法的流程是:将所有的节点分为A、B的两个集合,一开始A集合中只有起点,其他的节点在B集合。定义B中的节点与A的距离:若邻接A中的结点,则距离为边权;反之距离无穷大。1.找到与A距离最小......
  • 基于深度学习的停车场车辆检测算法matlab仿真
    1.算法运行效果图预览   上图测试结果如下图所示:   2.算法运行软件版本matlab2022a 3.算法理论概述     随着城市交通管理和智慧停车系统的快速发展,停车场车辆检测已成为实现高效车位管理、智能计费的关键技术之一。深度学习,尤其是基于卷积神经网络(CN......
  • 数据结构与算法
    1数据结构1.1动态数组①数组特点存储特点:连续存储优点:查找块,访问元素快缺点:插入、删除元素效率低②实现思路1.初始化:malloc()动态分配内存区域2.扩展长度:realloc()重新调整内存区域大小3.插入元素:插入位置,后面所有元素后移4.删除元素:删除位置,后面所有元......
  • 先进先出算法
    一、意义目的解决多个多个呼叫一个应答问题。如何排队,如何出队。常用于缓存多个请求,保持队列,先进先出。好处是有顺序,但是可以结合实际,比如位置比较近要先出,可以将“先进先出”作为排队出队子算法,再去排序,达到效率最高。二、原理:使用数组改变下标方式存入,出栈把后面变量一个......
  • 复杂网络社区发现算法聚类分析全国电梯故障数据和可视化:诊断电梯“安全之殇”|附代码
    参考原文:http://tecdat.cn/?p=2186最近我们被客户要求撰写关于复杂网络社区发现算法的研究报告,包括一些图形和统计输出。物业工程肩负着维持项目各类设施设备的正常运作,保障全体业主的正常生活,令物业保值升值,是项目的心脏部门。拓端数据(tecdat)研究人员根据全国电梯故障上报汇总......
  • 29天【代码随想录算法训练营34期】第七章 回溯算法part05 (491.递增子序列 * 46.全排
    491.递增子序列如果在最前面加一个uset=set(),这个就是给这一层一个usedset,很好用,不错classSolution:deffindSubsequences(self,nums:List[int])->List[List[int]]:result=[]self.backtracking(nums,[],result,0)returnresult......