KMP算法next数组构建形式(几种常见的形式+例题)
第一種形式
數據結構實驗之串一:KMP簡單應用
Time Limit:?1000 ms?Memory Limit:?65536 KiB
Submit?Statistic
Problem Description
給定兩個字符串string1和string2,判斷string2是否為string1的子串。
Input
?輸入包含多組數據,每組測試數據包含兩行,第一行代表string1(長度小于1000000),第二行代表string2(長度小于1000000),string1和string2中保證不出現空格。
Output
?對于每組輸入數據,若string2是string1的子串,則輸出string2在string1中的位置,若不是,輸出-1。
Sample Input
abc a 123456 45 abc dddSample Output
1 4 -1Hint
?
Source
cjx
代碼如下:
#include<stdio.h> #include<string.h> #include<stdlib.h>char str1[1000001] ; char str2[1000001] ; int next[1000001] ;void set() {int j = -1;int i = 0 ;int len =strlen(str2) ;next[0] = -1 ;while(i<len){if(j == -1 || str2[i] == str2[j]){i++ ;j++ ;next[i] =j ;}else j = next[j] ;} }int find() {int len1 , len2 ;int i ,j ;len1 = strlen(str1) ;len2 = strlen(str2) ;i = 0 ; j = 0 ;while(i<len1&&j<len2){if(str1[i] == str2[j] || j == -1){i++ ;j++ ;}else j = next[j] ;}if(j == len2 ){return i-len2+1 ;}else return -1 ; }int main() {int pos ;while(~scanf("%s %s",str1,str2)){set() ; //構建next數組pos = find() ; //返回子串在主串的位置printf("%d\n",pos) ;}return 0 ; }?
第二種形式(對next數組的優化)
題同上
#include<stdio.h> #include<string.h> #include<stdlib.h>char a[1000001] ; char b[1000001] ; int next[1000001] ;void set() {int len = strlen(b) ;int i = 0 ;next[0] = -1 ;int j = -1 ;while(i<len){if(j == -1||b[i] == b[j]){i++ ;j++ ;if(b[i]!=b[j]){next[i] = j ;}else next[i] = next[j] ;}else j = next[j] ;} }int kmp() {int l1 = strlen(a) ;int l2 = strlen(b) ;int i = 0 ;int j = 0 ;while(i<l1&&j<l2){if(j == -1||a[i] == b[j]){i++ ;j++ ;}else j = next[j] ;}if(j == l2)return i - l2 +1 ;else return -1 ; }int main() {while(~scanf("%s",a)){scanf("%s",b) ;set() ; //創建next數組int d = kmp() ;printf("%d\n",d) ;}return 0 ; }?
第三種形式(最大長度表)
Good Luck!
Time Limit:?1000 ms?Memory Limit:?65536 KiB
Submit?Statistic
Problem Description
我們都知道,前綴就是一個單詞的前幾個字母(長度小于單詞長度);后綴就是一個單詞的后幾個字母(長度小于單詞長度)。例如:Hello,{H,He,Hel,Hell}都是Hello的前綴,{ello,llo,lo,o}都是Hello的后綴。現在,給你一個字符串String,你的任務是找出一個字串s,s既是String的前綴,又是String的后綴,并且s也出現在String的中間部分(既不是前綴,也不是后綴),s的長度越長越好。
Input
輸入一個N,接下來N行,每行一個字符串String,String長度len( 1 <= len <= 1000000)。
Output
輸出只有一行,如果有符合條件的s,輸出長度最長的s,如果沒有,輸出“Bad Luck!”(不含引號)。
Sample Input
3 abcabcabcabcabc papapapap aaabaaaababSample Output
abcabcabc papap Bad Luck!Hint
?
Source
GLSilence
?
代碼如下:
import java.util.Scanner;public class Main{static int next[] = new int[1000001] ; public static void main(String[] args) {Scanner sc = new Scanner(System.in) ; int t= sc.nextInt() ; sc.nextLine(); while(t-->0){String str = sc.nextLine() ;setNext(str) ;int len = str.length() ; if(len<3||next[len-1]==-1){System.out.println("Bad Luck!");}else {int l = len-1; boolean tag = false ;while(next[l]!=-1){if(str.indexOf(str.substring(0,next[l]+1),1)!=len-1-next[l]){System.out.println(str.substring(0,next[l]+1));tag = true ; break ; }l = next[l] ; }if(!tag)System.out.println("Bad Luck!");}}sc.close() ; }private static void setNext(String str) {int j ; j = -1 ; next[0] = -1 ; for(int i= 1 ;i<str.length() ;i++){while(j!=-1&&str.charAt(i)!=str.charAt(j+1))j = next[j] ; if(str.charAt(i) == str.charAt(j+1))j++ ; next[i] = j ; }} }參考文章:https://blog.csdn.net/v_JULY_v/article/details/7041827?
?
總結
以上是生活随笔為你收集整理的KMP算法next数组构建形式(几种常见的形式+例题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【小程序】C语言实现简易钢琴-利用sin
- 下一篇: SkiaSharp 之 WPF 自绘时钟