暴力
import java.util.Scanner;
public class trybaoLi22_3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个字符串:");
String S1 = input.nextLine();
System.out.println("请输入第二个字符串:");
String S2 = input.nextLine();
int index = match(S1, S2);
if (index >= 0) {
System.out.println(index);
} else {
System.out.println("No search");
}
}
public static int match(String S1, String S2) {
for (int i = 0; i < S1.length() - S2.length() + 1; i++) {
if (isMathed(i, S1, S2)) {
return i;
}
}
return -1;
}
public static boolean isMathed(int i, String S1, String S2) {
for (int k = 0; k < S2.length(); k++) {
if (S2.charAt(k) != S1.charAt(i + k)) {
return false;
}
}
return true;
}
KMP
JAVA语言程序设计第22章第3题 22.3
import java.util.Scanner;
public class tryKMP22_3B {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个字符串:");
String S1 = input.nextLine();
System.out.println("请输入第二个字符串:");
String S2 = input.nextLine();
int index = KPM(S1, S2);
if (index >= 0) {
System.out.println(index);
} else {
System.out.println("No search");
}
}
private static int KPM(String S1, String S2) {
int[] fail = getFailure(S2);
int i = 0;// index on S1
int j = 0;// index on S2
while (i< S1.length())
if(S1.charAt(i) == S2.charAt(j)){
if(j==S2.length()-1){
return i-S2.length()+1; // S2 mathcd
}
i++;
j++;
}else{
if(j>0){
j= fail[j-1];
}
else{
i++;
}
}
return -1;
}
public static int[] getFailure(String S2){
int[] fail = new int[S2.length()];
int i = 1;
int k = 0;
while(i<S2.length()){
if(S2.charAt(i)==S2.charAt(k)){
fail[i] = k+1;
i++;
k++;
}else if (k>0){
k=fail[k-1];
}else{
i++;
}
}
return fail;
}
我的改进的KMP更易看懂
import java.util.Arrays;
import java.util.Scanner;
public class tryKMP22_3I {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个字符串:");
String S1 = input.nextLine();
System.out.println("请输入第二个字符串:");
String S2 = input.nextLine();
int index = KPM(S1, S2);
if (index >= 0) {
System.out.println(index);
} else {
System.out.println("No search");
}
}
// KMP方法查找 匹配字符串
private static int KPM(String S1, String S2) {
int[] next = nextCreat(S2);
int yiPiPei = 0;
for (int i = 0, j = 0; i < S1.length(); i++) {
// while (j > 0 && S1.charAt(i) != S2.charAt(j)) { // 不匹配
if (j > 0 && S1.charAt(i) != S2.charAt(j)) { // 不匹配
j = next[j - 1]; // 找到前面 对应的部分匹配值
// System.out.println(" " + i + " "+ j);
i = i + yiPiPei - j; // 移动位数 = 已匹配的字符数 - 对应的部分匹配值
// System.out.println(i);
yiPiPei = 0; // 已经没有 一匹配的字符数了
}
if (S1.charAt(i) == S2.charAt(j)) { // 匹配
j++;
yiPiPei = j; // 匹配个数同步
}
if (j == S2.length()) {
return i - j + 1;
}
}
return -1;
}
// 创建字符串的next数组
//
// 在暴力算法的基础上通过next数组回溯 j 来减少时间复杂度
//
// 移动位数 = 已匹配的字符数 - 对应的部分匹配值
// "部分匹配"的实质是,有时候,字符串头部和尾部会有重复。
// 比如,"ABCDAB"之中有两个"AB",那么它的"部分匹配值"就是2("AB"的长度)。
// 搜索词移动的时候,第一个"AB"向后移动4位(字符串长度-部分匹配值),就可以来到第二个"AB"的位置。
// 这个方法可以找出 部分匹配表
private static int[] nextCreat(String S2) {
int[] next = new int[S2.length()];
next[0] = 0;
// i 是源字符串下标 j 是
for (int i = 1, j = 0; i < S2.length(); i++) {
while (j > 0 && S2.charAt(i) != S2.charAt(j)) {// 不匹配
j = next[j - 1]; // 回溯收回
}
if (S2.charAt(i) == S2.charAt(j)) { // 匹配成功
j++; //
}
next[i] = j;
}
System.out.println(Arrays.toString(next));
return next;
}
// 初始化next数组
//
// 前后缀不相同的情况:j重复回退j=next[j-1],直到j==0或前后缀相同
//
// 前后缀相同情况:j++
//
// 给next数组赋值next[i]=j
Boyer-Moore
import java.util.Scanner;
public class Boyer_Moore {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个字符串:");
String S1 = input.nextLine();
System.out.println("请输入第二个字符串:");
String S2 = input.nextLine();
int index = BoM(S1, S2);
if (index >= 0) {
System.out.println(index);
} else {
System.out.println("No search");
}
}
public static int BoM(String S1, String S2) {
int i = S2.length() - 1; // 总的固定的
while (i < S1.length()) {
int j = S2.length() - 1; // 索引S2
int k = i; // 索引S1
while (j >= 0) {
if (S1.charAt(k) == S2.charAt(j)) {
j--;
k--;
} else {
break;
}
}
if (j < 0)
return k+1;
int h = huaDong(j - 1, S2, S1.charAt(k));
if (h > 0) {
i = i + h;
} else if (h < 0) {
i = i + S2.length();
} else {
i = i + 1;
}
}
return -1;
}
public static int huaDong(int j, String S2, char wei) {
int weiZhi = 0;
// System.out.println(wei + " " + j);
while (j >= 0) {
if (wei == S2.charAt(j)) {
return weiZhi;
}
j--;
weiZhi++;
}
return -1;
}