学密码学一定得学程序(SDUTOJ_2463)

题目描述

曾经,ZYJ同学非常喜欢密码学。有一天,他发现了一个很长很长的字符串S1。他很好奇那代表着什么,于是神奇的WL给了他另一个字符串S2。但是很不幸的是,WL忘记跟他说是什么意思了。这个时候,ZYJ不得不求助与伟大的ZP。ZP笑了笑说,这个很神奇的,WL的意思是只要你找到她给你的字符串在那个神奇的字符串的位置,你就会有神奇的发现。ZYJ恍然大悟,原来如此,但是悲剧来了,他竟然不知道怎么找。。。。是的,很囧是不是。所以这时候就需要化身为超级玛丽亚的你现身了,告诉他吧。。。。。。

输入

首先输入一个n。表示有n组测试数据。

每组测试数据有两行。

第一行为字符串S1,长度不大于1000000。

第二行为字符串S2,长度不大于10000,并且长度不小于2。

输出

输出S2在S1的位置。如果有多个位置,只输出第一个位置。

如果找不到,就输出“::>_<::“(不输出双引号)。

示例输入

1
ASDFGDF
DF

示例输出

3

最基础的kmp的运用,kmp我是在博客上学的,个人感觉这篇博文还不错,附上链接http://blog.csdn.net/sjf0115/article/details/8579484

代码

#include <iostream>
#include <cstring>

using namespace std;

void get_nextval(string pattern,int next[])
{
    int j=0,k=-1;
    next[0]=-1;
    while(pattern[j]!='\0')
    {
        if(k==-1||pattern[j]==pattern[k])
        {
            j++;
            k++;
            if(pattern[j]==pattern[k])
                next[j]=next[k];
            else
                next[j]=k;
        }
        else
            k=next[k];
    }
}

int kmp(string text,string pattern)
{
    if(text[0]=='\0'||pattern[0]=='\0') 
        return -1;
    int len=pattern.length();
    int *next=new int[len+1];
    get_nextval(pattern,next);
    int index=0,i=0,j=0;
    while(text[i]!='\0'&&pattern[j]!='\0')
    {
        if(text[i]==pattern[j])
        {
            i++;
            j++;
        }
        else
        {
            index+=j-next[j];
            if(next[j]!=-1)
                j=next[j];
            else
            {
                j=0;
                i++;
            }
        }
    }
    if(pattern[j]=='\0') return index+1;
    else return -1;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    string text,pattern;
    cin>>n;
    while(n--)
    {
        cin>>text>>pattern;
        if(kmp(text,pattern)!=-1) cout<<kmp(text,pattern)<<endl;
        else cout<<"::>_<::"<<endl;
    }
    return 0;
}

你可能感兴趣的:(学密码学一定得学程序(SDUTOJ_2463))