本文主要介绍普通的串匹配算法,这种算法的特点是好想,但是消耗时间,不够高效,在牛客上做题时遇到这种题,一般情况下是通不过的。该算法为后面的KMP算法做一个铺垫。
思路:
从源字符串的第一个字符开始与子字符串的第一个字符开始比较,字符相同,继续比较下一个字符,遇到不相同的,源字符串回溯到第二个字符,子字符串回溯到第一个字符,再次比较….直到循环停止。
我的代码:
package com.zhangyike.StringNormal;
import java.util.Scanner;
public class StringMatch {
public static void main(String[] args) {
Scanner can = new Scanner(System.in);
try{
String str = can.nextLine();
String subStr = can.nextLine();
if (filter(str,subStr)) {
if (str.length() < subStr.length()) {
System.out.println(-1);
}else{
int index = findSubString(str,subStr);
System.out.println(index);
}
}else{
System.out.println("输入不合法!");
}
}finally{
can.close();
}
}
private static int findSubString(String str, String subStr) {
int i = 0;
int j = 0;
for (i = 0; subStr.length() <= str.length() - i; i++) {
int index = i;
for (j = 0; j < subStr.length() && str.charAt(index) == subStr.charAt(j); j++,index++) {
;
}
if (j == subStr.length()) {
return index - subStr.length();
}
}
return -1;
}
private static boolean filter(String str, String subStr) {
if (str != null && str.length() > 1 && subStr != null && subStr.length() > 1 ) {
return true;
}
return false;
}
}
String、StringBuffer、StringBuider的indexOf(str,index)也是在源字符串中查找子串的出现的下标,他的思路跟我的思路大致是一样的,代码如下:
static int indexOf(char[] source, int sourceOffset, int sourceCount,char[] target, int targetOffset, int targetCount, int fromIndex) {
/*参数的检验,具体怎么检验的,我之前博客有专门写,想了解的可以去看看我之前的博客。*/
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* 找到子字符串的第一个字符在源串中出现的位置*/
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* 找到第一个位置之后,再看剩下的其他字符是否匹配 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
/*依次匹配,遇到不合适的再次返回while循环,继续寻找子字符串第一个字符在源串中出现的下标。*/
for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++);
if (j == end) {
/* 找到了完成的子串,就把子串第一个字符在源串出现的下标返回。 */
return i - sourceOffset;
}
}
}
return -1;
}