字符串搜索
暴力算法
Hash算法(求和)
BM算法
KMP算法
package SF;
/*
* 字符串查找
* 1、BF算法
* 2、RK算法
* 3、BM算法
* */
public class Stringsearch {
public static void main(String[] args) {
String str1="ABCACBCAABCDB";
String str2="ABCDB";
System.out.println(search(str1,str2));
System.out.println(search1(str1,str2));
System.out.println(search2(str1,str2));
}
/*
* 1、暴力循环
* */
public static int search(String str1,String str2){
int m=str1.length();
int n=str2.length();
if (m<n)return -2;
for (int i = 0; i <=m-n; i++) {
int j;
for ( j = 0; j <n; j++) {
if(str1.charAt(i+j)!=str2.charAt(j))break;
}
if(j==n)return i+1;
}
return -1;
}
/*
* 2、RK算法,利用hash函数获取哈希值
* */
public static int search1(String str1,String str2){
int m=str1.length();
int n=str2.length();
if (m<n)return -2;
int str2hash=hashfunction(str2);
for (int i = 0; i <=m-n; i++) {
String s=strsplit(str1,i,n);
if (hashfunction(s)==str2hash)return i+1;
}
return -1;
}
public static int hashfunction(String str){
int m=str.length()*10000;
for (int i = 0; i < str.length(); i++) {
m+= (int) str.charAt(i)*i;
}
return m;
}
public static String strsplit(String str,int start,int length){
if ((start+length)>str.length()) System.err.println("不可分割");
char[] chars=new char[length];
for (int i = 0; i < length; i++) {
chars[i]=str.charAt(i+start);
}
return new String(chars);
}
/*
* 3、BM算法,计算最佳移动步长
* */
public static int search2(String str1,String str2){
int m=str1.length();
int n=str2.length();
if (m<n)return -2;
int move=0;
for (int c = 0; c <= m-n; c=c+move+1) {
//查找
String buf=strsplit(str1,c,n);
if (hashfunction(buf)==hashfunction(str2))return c+1;
//计算移动步长
StringBuilder goodstr= new StringBuilder();
char badstr = 0;
int moveg=0;//好字符移动步长
int moveb=0;//坏字符移动步长
int index=0;
//查找好字符和坏字符
for (int i = n-1; i >=0; i--) {
if(str2.charAt(i)==buf.charAt(i)) goodstr.append(str1.charAt(i));
else {badstr=buf.charAt(i);index=i;break;};
}
//计算坏字符移动步长
for (int i = index-1; i >=0; i--) {
if (badstr==str2.charAt(i)){
moveb=index-i;
break;
}
}
//计算好字符移动步长
goodstr.reverse();
String goodstr1= String.valueOf(goodstr);
for (int i = index-goodstr.length(); i >=0; i--) {
String newstr=strsplit(str2,i,goodstr.length());
if(newstr.equals(goodstr1)){
moveg=index-i+1;
break;
}
}
//取最大步长
move=Math.max(moveb,moveg)-1;
if (move<0)move=0;
}
return -1;
}
}
import java.util.*;
public class StringPattern {
//kmp算法 next算法
public int[] getNextArray(char[] ms){
if(ms.length==1){
return new int[]{-1};
}
int[] next=new int[ms.length];
next[0]=-1;
next[1]=0;
int pos=2;
int cn=0;
while(pos<next.length){
if(ms[pos-1]==ms[cn]){
next[pos++]=++cn;
}else if(cn>0){
cn=next[cn];
}else{
next[pos++]=0;
}
}
return next;
}
public int findAppearance(String A, int lena, String B, int lenb) {
// write code here
if(A==null||B==null||A.length()<1||A.length()<B.length()){
return -1;
}
char[] As=A.toCharArray();
char[] Bs=B.toCharArray();
int Ai=0;
int Bi=0;
int[] next=getNextArray(Bs);
while(Ai<As.length&&Bi<Bs.length){//核心算法
if(As[Ai]==Bs[Bi]){//相等一直往后移动
Ai++;
Bi++;
}else if(next[Bi]==-1){//不相等,且其next数组为-1,从原字符串下一个字符开始比较
Ai++;
}else{
Bi=next[Bi];//不相等,把Bs往后移动
}
}
return Bi==Bs.length?Ai-Bi:-1;//返回下标
}
}