KMP算法 - 字符串匹配的简单运用 --- HDU 1711

Number Sequence

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11606    Accepted Submission(s): 5294

Problem Description

Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.

Input

The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <= 1000000). The second line contains N integers which indicate a[1], a[2], ...... , a[N]. The third line contains M integers which indicate b[1], b[2], ...... , b[M]. All integers are in the range of [-1000000, 1000000].

Output

For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead.

Sample Input

2

13 5

1 2 1 2 3 1 2 3 1 3 2 1 2

1 2 3 1 3

13 5

1 2 1 2 3 1 2 3 1 3 2 1 2

1 2 3 2 1

Sample Output

6



Mean:

给你s1,s2两个串,让你找到s2在s1中出现的第一个位置。

analyse:

KMP字符串水题,用c++写的,其实真正理解了KMP算法后,你会发现一点都不难。

Time complexity:O(n)  抓住:主串不回溯

Source code:

// Memory   Time
// 1347K     0MS
// by : Snarl_jsb
// 2014-09-28-14.33
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<climits>
#include<cmath>
#define N 1000010
#define LL long long
using namespace std;

int n,m;
vector<int> a,b;
vector<int> next;
void GetNext()
{
    int k=0;
    int len=b.size();
    next.push_back(0);
    for(int i=1;i<len;++i)
    {
        while(k!=0&&b[i]!=b[k])
            k=next[k-1];
        if(b[i]==b[k])
            k++;
        next.push_back(k);
    }
//    for(int i=0;i<next.size();++i)
//        cout<<next[i]<<endl;
}
void KMP()
{
    GetNext();
    bool flag=0;
    int asize=a.size(),bsize=b.size(),k=0;
    for(int i=0;i<asize;++i)
    {
        while(k>0&&a[i]!=b[k])
        {
            k=next[k-1];
        }
        if(a[i]==b[k])
            k++;
        if(k==m)
        {
            cout<<i-m+2<<endl;
            flag=1;
            break;
        }
    }
    if(!flag) puts("-1");
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
//    freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin);
//    freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout);
    int t,tmp;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        a.clear(),b.clear(),next.clear();
        for(int i=0;i<n;++i)
        {
            cin>>tmp;
            a.push_back(tmp);
        }
        for(int i=0;i<m;++i)
        {
            cin>>tmp;
            b.push_back(tmp);
        }
        KMP();
    }
    return 0;
}

  

时间: 2024-09-30 17:52:02

KMP算法 - 字符串匹配的简单运用 --- HDU 1711的相关文章

KMP算法字符串匹配

对于暴力搜索法,当搜索词对应的字符与字符串中的字符不匹配时.将搜索词整个后移一位,再从头逐个比较.这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍. 应用KMP算法之后,则有: 移动位数=已匹配的字符数?对应的部分匹配值 "部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度. KMP算法实现代码如下: void prefixFun(char *pattern, int *preFun)

KMP算法---字符串匹配

算法细节详见点击打开链接和点击打开链接 #include <stdio.h> #include <stdlib.h> #define N 7 #define M 15 void showpset(int* a); void cal_pset(char* a, int* p,int n); int KMP(char* a,char* b,int* P); int main(void) { char a[M]={'a','b','a','c','a','b','a','a','b','

swift算法实践(3)-KMP算法字符串匹配

    版权声明:本文为博主原创文章,未经博主允许不得转载.

算法——字符串匹配之KMP算法

前言 本节介绍Knuth-Morris-Pratt字符串匹配算法(简称KMP算法).该算法最主要是构造出模式串pat的前缀和后缀的最大相同字符串长度数组next,和前面介绍的<朴素字符串匹配算法>不同,朴素算法是当遇到不匹配字符时,向后移动一位继续匹配,而KMP算法是当遇到不匹配字符时,不是简单的向后移一位字符,而是根据前面已匹配的字符数和模式串前缀和后缀的最大相同字符串长度数组next的元素来确定向后移动的位数,所以KMP算法的时间复杂度比朴素算法的要少,并且是线性时间复杂度,即预处理时间复

算法学习-KMP(字符串匹配)解释

KMP算法 BF算法 BF算法就是我们最基本的求解字符串匹配的算法,算法的时间复杂度为O(M*N),空间复杂度为O(1),具体过程如下: 串 第一次 第二次 第三次 第四次 模式串S[i] abcababc abcababc abcababc abcababc 匹配串T[j] ababc ababc ababc ababc 可以看到在第三次匹配失败的时候,我们要回溯,直接S串直接i+=1,然后T串j=0从头继续开始.这样复杂度就比较高了. KMP算法 而KMP算法就是为了解决BF算法的复杂度比

算法——字符串匹配之BM算法

前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左开始比较,但模式串的移动依然是从左到右的.在实践中,BM算法效率高于前面介绍的<KMP算法>,算法分为两个阶段:预处理阶段和搜索阶段:预处理阶段时间和空间复杂度都是是O(m+sigma),sigma是字符集大小,一般为256:在最坏的情况下算法时间复杂度是O(m*n):在最好的情况下达到O(n/m). BM算法实现 BM算法预处理过程 BM算法有两个规则分别为坏字符规则(Bad Cha

kmp算法模式串匹配

转载:字符串匹配 kmp算法

算法——字符串匹配之有限自动机算法

前言 上篇文章介绍<Rabin-Karp字符串匹配算法>,这里介绍有限自动机(Finite Automata)字符串匹配算法,有限自动机(Finite Automata)字符串匹配算法最主要的是计算出转移函数.即给定一个当前状态k和一个字符x,计算下一个状态:计算方法为:找出模式pat的最长前缀prefix,同时也是pat[0...k-1]x(注意:字符串下标是从0开始)的后缀,则prefix的长度即为下一个状态.匹配的过程是比较输入文本子串和模式串的状态值,若相等则存在,若不想等则不存在.有

算法——字符串匹配之Rabin-Karp算法

前言 Rabin-Karp字符串匹配算法和前面介绍的<朴素字符串匹配算法>类似,也是对应每一个字符进行比较,不同的是Rabin-Karp采用了把字符进行预处理,也就是对每个字符进行对应进制数并取模运算,类似于通过某种函数计算其函数值,比较的是每个字符的函数值.预处理时间O(m),匹配时间是O((n-m+1)m). Rabin-Karp算法实现 伪代码: Rabin_Karp_search(T, P, d, q) n = T.length; m = P.length; h = d^(m-1)mo