kmp及其运用

一、算法介绍

D.E. Knuth、 JH.Morris和 R. Pratt(其中 Knuth和Prat共同研究, Morris独立研究)发表一个模式匹配算法,可以大大避免重复遍历的情况,我们把它称之为克努特一莫里斯一普拉特算法,简称KMP算法

两个我觉得讲的可以的视频

  1. 算法介绍:https://www.bilibili.com/video/BV1Ys411d7yh
  2. 介绍&&代码复现:https://www.bilibili.com/video/BV1hW411a7ys

KMP算法核心部分就是获取匹配数组(有的叫next,有的叫pattern数组):

kmp及其运用_第1张图片

代码实现时需要注意有的用-1表示,有的用0表示开始

二、相关题目

1. LeetCode 28. 实现 strStr()

 实现 strStr() 函数。

 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2

示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1

说明:

 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

C代码实现:

int* get_next(char* needle){
    int lenOfneedle=strlen(needle);
    int* next=(int *) malloc(sizeof(int)*lenOfneedle);
    next[0] = -1;
    int j = 0;
    int k = -1;
    while(j

C++代码实现

class Solution {
public:
    vector getNext(string pattern){
        int len=pattern.size();
        vector next(len);
        int i=-1,j=0;
        next[0]=-1;
        while(j next=getNext(needle);
        int i=0,j=0;
        int len1=haystack.size(),len2=needle.size();
        while(i

 需要注意的是C++中main函数while循环里的“i

2. 查找字符串最长公共子串

 请编码实现一个命令行工具,找出指定的2个字符串的最长公共子串。

输入描述:
命令行工具接收两个字符串参数。输入字符串的合法字符集为[a-zA-Z0-9],大小写敏感,无需考虑异常输入场景。
输出描述:
所找到的公共子串;如果存在多个等长的公共子串,则请按字母序排序,依次打印出所有公共子串,每行一个。

示例1

输入

1234567 12893457

输出

345

 这里可以用枚举(顺序表)+KMP,也可以用动态规划,这里先贴dp的代码(评论区)

#include
#include
#include
#include
using namespace std;
 
void findLCStr(string A, int n, string B, int m) {
    int c[n+1][m+1];
    pair p[min(n,m)];
    int i,j,k,res=0,res_end=0,cnt=0;//res 最长公共子串长度,res_end最长公共子串末尾序号
    for(i=0;i<=n;i++) c[i][0]=0;
    for(j=1;j<=m;j++) c[0][j]=0;
 
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(A[i-1]==B[j-1]){
                c[i][j] = c[i-1][j-1] + 1;
                if(res<=c[i][j]){
                    res = c[i][j];
                    res_end = i;
                    string t="";
                    p[cnt].first=res;
                    for(k=res_end-1-res+1;k<=res_end-1;++k)
                        t+=A[k];
                    p[cnt++].second=t;
                }
                //res = max(res, c[i][j]);
            }
            else c[i][j] = 0;    //与LCS的区别在这里
        }
    }
    sort(p,p+cnt);
    for(i=0;i>A>>B;
    findLCStr(A,A.length(),B,B.length());
}

你可能感兴趣的:(C++)