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");
    }
    
  • 相关阅读:
    sql分页存储过程疑惑:Row_Number与临时表哪个好?
    SQL之剪切
    在sqlserver2005中安装sql server 2000的示例数据库northwind
    安装SQL2005示例数据库
    Firefox浏览器中,Flex的FileReference上传文件,引发IOError
    Java获取方法的调用者
    ABAP screen常见语法
    XPO永久删除记录方法
    XPO的UpCasting
    在ASP.NET项目中使用XPO的最佳准则
  • 原文地址:https://www.cnblogs.com/Aliencxl/p/13228501.html
Copyright © 2011-2022 走看看