题目描述
给定两个字符串str和match,长度分别为N和M。实现一个算法,如果字符串str中含有子串match,则返回match在str中的开始位置,不含有则返回-1
若出现了多次,则按照升序输出所有出现位置
[要求]
时间复杂度为O(n)
输入描述:
第一行一个字符串str
第二行一个字符串match
输出描述:
输出若干个数,分别为match在str中出现的位置,从0开始标号。
若不存在输出-1
示例1
输入
acbc
bc
输出
2
示例2
输入
acbc
bcc
输出
-1
示例3
输入
ababab
ab
输出
0 2 4
解法一:KMP
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s1 = br.readLine().trim();
String s2 = br.readLine().trim();
match(s1,s2);
}
public static void match(String s1,String s2){
if(s1==null||s2==null||s1.length()<s2.length()||s2.length()<1){
return;
}
StringBuilder sb = new StringBuilder();
char[] arr1 = s1.toCharArray();
char[] arr2 = s2.toCharArray();
int[] next = getNext(arr2);
int l1 = 0;
int l2 = 0;
while(l1<s1.length()&&l2<s2.length()){
if(arr1[l1]==arr2[l2]){
l1++;
l2++;
}else if(next[l2]>=0){
l2 = next[l2];
}else{
l1++;
}
if(l2==s2.length()){
sb.append((l1-l2)+" ");
l2 = 0;
}
}
if(sb.length()==0) sb.append("-1");
System.out.println(sb.toString().trim());
}
public static int[] getNext(char[] s){
if(s.length==1) return new int[]{-1};
int [] next = new int[s.length];
next[0] = -1;
next[1] = 0;
int p = 2;
int cn = 0;
while(p<s.length){
if(s[p-1]==s[cn]){
next[p++] = ++cn;
}else if(cn>0){
cn = next[cn];
}else{
next[p++] = 0;
}
}
return next;
}
}