zoukankan      html  css  js  c++  java
  • KMP算法入门

    KMP算法


    理解

    KMP算法的核心,是一个被称为部分匹配表(Partial Match Table)的数组。我觉得理解KMP的最大障碍就是很多人在看了很多关于KMP的文章之后,仍然搞不懂PMT中的值代表了什么意思。这里我们抛开所有的枝枝蔓蔓,先来解释一下这个数据到底是什么。

    对于字符串“abababca”,它的PMT如下表所示:

    PMT中的值是字符串的前缀集合与后缀集合的交集中最长元素的长度

    我们看到如果是在 j 位 失配,那么影响 j 指针回溯的位置的其实是第 j −1 位的 PMT 值,所以为了编程的方便, 我们不直接使用PMT数组,而是将PMT数组向后偏移一位。我们把新得到的这个数组称为next数组。

    例题

    HDU1711

    给定两个数组,问能不能再第一个数组中匹配得到第二个数组,如果可以,那么输出最早匹配的起始位置,否则输出-1

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int s[1000005],p[10005], ne[10005];//next是关键字
    int n, m;
    
    void getNext(){
        int i = 0, j = -1;
        ne[0] = -1;
        while(i < m){
            if(j == -1 || p[i] == p[j]){
                i++; j++; ne[i] = j; //attention!
            }
            else j = ne[j];
        }
    }
    int KMP(){
        int i = 0, j = 0;
        getNext();
        while(i < n &&j <m){
            if(j == -1 || s[i] == p[j]){
                i++; j++;
            }
            else j = ne[j];
        }
        if(j == m) return i - j + 1;
        return -1;
    }
    int main(){   
        int t;
        cin >> t;
        while(t--){
            cin >> n >> m;
            for(int i = 0; i <n; i++) scanf("%d",&s[i]);
            for(int i = 0; i < m ;i++) scanf("%d",&p[i]);
            int t = KMP();
            cout << t << endl;
        }
        system("pause");
    }
    
  • 相关阅读:
    随机生成4位验证码(包含数字, 字母)
    eval注册和登录
    51单片机中断机制(定时器/计数器)
    CS106B
    机器学习算法之旅(转载)
    Ubuntu系统使用记录
    2. 自然语言处理预备知识
    1. 自然语言处理描述
    前端学习网站
    2016年总结,2017年计划
  • 原文地址:https://www.cnblogs.com/Aliencxl/p/13228501.html
Copyright © 2011-2022 走看看