首页 > 编程语言 >kmp算法

kmp算法

时间:2023-06-13 15:34:38浏览次数:39  
标签:子串 ++ next int 算法 kmp now

问题描述

kmp算法解决的是字符串匹配问题,即:字符串P是否是字符串S的子串?如果是,它出现在s的哪些位置?这里我们称 S 为主串,P 为模式串。

思路

首先是暴力匹配算法(Brute-Force算法),代码如下:

void BruteForce(string s, string p) {
    int len_s = s.size(), len_p = p.size();
    for (int i = 0; i <= len_s - len_p; ++i) {
        int flag = true;
        for (int j = 0; j < len_p; ++j) {
            if (s[i + j] != p[j]) {
                flag = false;
                break;
            }
        }
        if (flag) {
            printf("pos = %d\n", i);
        }
    }
}

易得时间复杂度的最坏情况是$O(mn)$的,其中$n$为s的长度,$m$为p的长度。

为了降低字符串比较的复杂度,我们就必须降低比较的趟数,kmp算法的主要思想就是尽可能利用残余信息,即字符串如果在 j = r 处匹配失败了,那么前r个字符一定匹配成功了,暴力算法中,我们每次不匹配的情况下,都让j = 0,即模式串又从头开始匹配,这就完全没有利用比较带来的信息。

这里,我们可以找模式串的前缀子串和后缀子串,并得到对前r个字符组成的字符串,相等的前缀子串和后缀子串的最大长度,例如 p = "aabaac",那么对前$5$个字符,这个最大长度为2,所以对模式串 p 应该从 j = 2 处开始继续匹配,主串的 i 保持不变

因此,我们建立一个 next 数组,next[0] = 0next[k - 1] 表示前$k$个字符组成的字符串中,相等的前缀子串和后缀子串的最大长度,当 s[i] != p[j] 时,j = next[j - 1]

下一步就是求 next 数组,假设遍历到 j = x 时,这个最大长度为 now ,即 next[x - 1] = now,那么当 p[x] == p[now]next[x++] = ++now,如果 p[x] != p[now],那么 now = next[now - 1]

代码

快速计算next数组的代码:

void SetNext(vector<int> &next, string needle) {
    int x = 1, now = 0;
    while (x < needle.size()) {
        if (needle[x] == needle[now]) {
            next[x++] = ++now;
        } else if (now != 0) {
            now = next[now - 1];
        } else {
            next[x] = 0;
            x += 1;
        }
    }
}

基于next数组进行比较的代码

int strStr(string s, string p) {
    int m = p.size(), n = s.size();
    vector<int> next(m);
    SetNext(next, p);
    int i = 0, j = 0;
    while (i < n && j < m) {
        if (s[i] == p[j]) {
            ++i;
            ++j;
        } else {
            if (j > 0) {
                j = next[j - 1];
            } else {
                ++i;
            }
        }
    }
    if (j >= m) {
        return i - m;
    }
    return -1;
}

参考

kmp算法-阮行止

标签:子串,++,next,int,算法,kmp,now
From: https://www.cnblogs.com/zwyyy456/p/17477654.html

相关文章

  • LRU 算法与 LFU 算法
    算法介绍LRULRU全称是LeastRecentlyUsed,即最近最久未使用算法。LRU根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高,它是页面置换算法的一种,也常用于缓存设计。LFULFU全称是LeastFrequentlyUsed,根据频率来选择要......
  • 代码随想录算法训练营第六天| 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数
    454.四数相加II1,难点:1,多个数组之间,会有重复出现的数组,如果单用multiset也是会出错的2,如果用mutliset,在使用distance找出来equal_range的值的时候,也是会出现奇怪的错误的2,正确思路1,把重复出现的节点,次数存放到map种,然后进行遍历3,代码:1intfourSumCount(v......
  • 湖边的烦恼-算法训练题
    湖边的烦恼-算法训练题-递归问题描述每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育......
  • ChatGPT之问艺道:如何借助神级算法Prompt,让你轻松get到更高质量答案?
    摘要:本文由葡萄城技术团队编写,文章的内容借鉴于IbrahimJohn的《TheArtofAskingChatGPT》(向ChatGPT提问的艺术)。前言当今,ChatGPT赢得越来越多人的青睐,人们通过它输入问题并获取答案。但除了简单的一问一答以外,ChatGPT还有许多隐藏的提问方式,是否想要一探究竟?今天,我们为您......
  • 代码随想录算法训练营第24天 | ● 理论基础 ● 77. 组合 - 第7章 回溯算法part01
     第七章 回溯算法part01今日内容: ●  理论基础 ●  77. 组合    详细布置   理论基础  其实在讲解二叉树的时候,就给大家介绍过回溯,这次正式开启回溯算法,大家可以先看视频,对回溯算法有一个整体的了解。 题目链接/文章讲解:https://programmercar......
  • 代码随想录算法训练营第25天 | ● 216.组合总和III ● 17.电话号码的字母组合 - 第7章
     第七章 回溯算法part02 今日内容:  ●  216.组合总和III●  17.电话号码的字母组合  详细布置   216.组合总和III  如果把 组合问题理解了,本题就容易一些了。  题目链接/文章讲解:https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%B......
  • 【基础算法】单链表的OJ练习(1) # 反转链表 # 合并两个有序链表 #
    前言上一章讲解了单链表==->==传送门==<-==,后面几章就对单链表进行一些简单的题目练习,目的是为了更好的理解单链表的实现以及加深对某些函数接口的熟练度。本章带来了两个题目。一是<fontcolor=red>反转链表</font>,二是<fontcolor=red>合并两个有序链表</font>,整体难......
  • 算法题:冒泡排序
    functionbubbleSort($arr){$len=count($arr);//获取要排序数组的长度for($i=0;$i<$len;$i++){//外层循环遍历整个数组for($j=0;$j<$len-$i-1;$j++){//内层循环用于比较相邻元素,次数随外层循环进行而减少if(......
  • 代码随想录算法训练营第五天| 242.有效的字母异位词 , 349. 两个数组的交集 , 202. 快
    242.有效的字母异位词 繁冗版:1,思路:先建立两个map,对应两个字符串对应的字符,同时对他们进行计数,如果这两个数字相等,那么就是相等2,代码1boolisAnagram_complicate(strings,stringt)2{3unordered_map<char,int>existedCharBys;45for(autoch......
  • 文心一言 VS 讯飞星火 VS chatgpt (39)-- 算法导论5.4 3题
    三、在生日悖论的分析中,要求各人生日彼此独立是否很重要?或者,是否只要两两成对独立就足够了?证明你的答案。文心一言:在生日悖论的分析中,要求各人生日彼此独立是非常重要的。这是因为,如果各人生日不是独立的,而是存在一定的相关性,那么就会影响到概率的计算,从而影响到生日悖论的分析结......