zoukankan      html  css  js  c++  java
  • kmp 算法回顾(Number Sequence HDU


    给定两个数字序列 a[] 和 b[]b[] 有可能整体作为一个连续子序列出现在了 a[] 中,现在请你找出 b[] 在 a[] 中第一次出现的位置(起始位置从 1 开始计数),如果一次都没有出现,请输出 -1。

    输入格式


    第一行包含一个数字 T,表示测试用例的个数。
    对于每组测试用例,第一行包含两个数字 n m ( 1<= n <= 1000000, 1 <= m <= 10000 ),表示 a[] 和 b[] 的长度。
    接下来的一行包括 n 个数字,依次表示 a[1], a[2], a[3] ... a[n]-1000000 <= a[i] <= 1000000 
    接下来的一行包括 m 个数字,依次表示 b[1], b[2], b[3] ... b[m]-1000000 <= b[i] <= 1000000

    输出格式


    对于每组数据输出一行,请输出 b[] 整体作为一个连续子序列在 a[] 中的首次出现位置的起始下标,如果一次都没有完整出现,输出 -1。

    样例输入


    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

    样例输出


    6
    -1

    样例解释


    对于第一组数据,1 2 1 2 3 [1 2 3 1 3] 2 1 2,首次出现位置的起始下标为 6。
    对于第二组数据,b[] 没有出现在 a[] 中,输出 -1。

    很久没有写字符串的题目了,也忘得差不多了

    最近打算学习字符串就先从kmp开始回顾

    kmp还是比较简单的

    大致思想就是使用使用get_nxt初始化一个出nxt数组

    运用nxt数组再每次失配时不移动文本串

    只对模式串进行移动

    对于nxt数组的理解就是当前的串跟前缀所能匹配的长度 然后往后串一位

    模板代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int a[1000005];
    int b[1000005];
    int nxt[1000005];
    void get_nxt()
    {
        int j,k;
        nxt[0]=-1;
        k=-1;
        j=0;
        while(j<m-1)
        {
            if(k==-1||b[j]==b[k])
            {
                k++;
                j++;
                nxt[j]=k;
            }
            else
            {
                k=nxt[k];
            }
        }
        return;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            for(int i=0;i<m;i++)
            {
                scanf("%d",&b[i]);
            }
            get_nxt();
            //for(int i=0;i<m;i++) cout<<nxt[i];
           // cout<<endl;
            int i=0,j=0;
            int ans=-1;
            while(i<n&&j<m)
            {
                if(j==-1||a[i]==b[j])
                {
                    j++;
                    i++;
                }
                else
                {
                    j=nxt[j];
                }
                if(j==m)
                {
                    ans=i-m+1;
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Android开发之Sqlite的使用
    ZOJ 3607 Lazier Salesgirl
    ZOJ 3769 Diablo III
    ZOJ 2856 Happy Life
    Ural 1119 Metro
    Ural 1146 Maximum Sum
    HDU 1003 Max Sum
    HDU 1160 FatMouse's Speed
    Ural 1073 Square Country
    Ural 1260 Nudnik Photographer
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852216.html
Copyright © 2011-2022 走看看