曾經,ZYJ同學非常喜歡密碼學。有一天,他發現了一個很長很長的字符串S1。他很好奇那代表著什么,于是神奇的WL給了他另一個字符串S2。但是很不幸的是,WL忘記跟他說是什么意思了。這個時候,ZYJ不得不求助與偉大的ZP。ZP笑了笑說,這個很神奇的,WL的意思是只要你找到她給你的字符串在那個神奇的字符串的位置,你就會有神奇的發現。ZYJ恍然大悟,原來如此,但是悲劇來了,他竟然不知道怎么找。。。。是的,很囧是不是。所以這時候就需要化身為超級瑪麗亞的你現身了,告訴他吧。。。。。。 Input
首先輸入一個n。表示有n組測試數據。
每組測試數據有兩行。
第一行為字符串S1,長度不大于1000000。
第二行為字符串S2,長度不大于10000,并且長度不小于2。 Output
輸出S2在S1的位置。如果有多個位置,只輸出第一個位置。
如果找不到,就輸出“::>_<::“(不輸出雙引號)。 Example Input
1ASDFGDFDFExample Output
3Hint
Author ZP
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <bits/stdc++.h> #define N 1010000 int i2, j2; void getnext(char *str, int *next, int slen) { int i=0, j; next[0]=-1;//存儲對稱與當前字符對稱的子串的末尾所在位置 while(i++<slen) { j=next[i-1];//取出前一字符所在位置的對稱信息 while(str[i]!=str[j+1]&&j>=0)//如果這個字符與前一字符對應對稱子串的末尾的下一字符不相同, 循環尋找 { j=next[j]; } if(str[i]==str[j+1])next[i]=j+1;//如果匹配 } } int kmp(char *str, int slen, char *ptr , int plen, int *next) { int i=-1, j=0; while(j<slen&&i<plen-1)//next存儲的為比較點前面的信息 { if(str[j]==ptr[i+1]) { i++; j++; } else { if(i==-1) { j++; } else { i=next[i];//進行該步驟后i仍然為比較點前面的信息 } } } if(i==plen-1)return j-i; else return -1; } int main() { char str[ N ] = {0}; char ptr[ 11000 ] = {0}; int next[ 11000 ]; int slen, plen; int t; scanf("%d", &t); getchar(); while( t-- ) { scanf( "%s%s", str, ptr); slen=strlen(str); plen=strlen(ptr); getnext(ptr, next, plen); int kk=kmp(str, slen, ptr, plen, next); if(kk!=-1)printf("%d/n", kk); else printf("::>_<::/n"); } return 0; }新聞熱點
疑難解答