此算法需要进行大量的回溯,效率较低。
/**
* 用暴力匹配算法完成字符串的匹配
* @author 冷了
*
*/
public class ViolentMatch {
public static void main(String[] args) {
/*需求:
* 有一个字符串 s1 = "AABBAABBCCBBAA",和一个子串 s2 = "ABBCC"
* 现在要判断string1是否包含string2,如果存在,就返回第一次出现的位置,如果没有,则返回-1。
*/
String s1 = "AAABBSNNEDEEED";
String s2 = "BSNNE";
System.out.println(violentMatch(s1,s2));//4
}
/**
* 将大串和小串传进去,进行字符串的匹配
* @param string1:大串
* @param string2:小串
* @return
*/
public static int violentMatch(String string1,String string2) {
//先将大串和小串转成字符数组
char[] s1 = string1.toCharArray();
char[] s2 = string2.toCharArray();
//得到两个字符数组的长度
int s1length = s1.length;
int s12ength = s2.length;
//定义两个变量,作为两个字符数组的索引
int i = 0; //作为大串的索引
int j = 0; //作为小串的索引
/*
* 有两种情况下会退出循环:
* 1:当大串索引到最后时就是(i < s1length)不满足时,为了防止越界而退出循环,也代表着大串已经找完了,没有发现与小串匹配的部分。
* 2:当小串索引到最后是就是( j < s12ength)不满足时,代表小串已经被大串完全匹配进而退出循环,此时的j == s12ength。
*/
while(i < s1length && j < s12ength) {
//当大字符数组中某个元素与小字符数组中某个元素相同时,两数组中的元素的下标都向后移动一位,以便下次判断双方后一位元素是否相等
if(s1[i] == s2[j]) {
i++;
j++;
//不满足时开始回溯
}else {
/*当大字符数组中的某个元素与小字符数组中某个元素不相同时,小字符数组的索引置为0(重新开始匹配),
大字符数组的索引回到上一次匹配小字符串最开始索引的后一位。*/
i = i - j + 1;//往后移动一位
j = 0; //索引重置,从头开始遍历
}
}
//当匹配成功时,此时小字符数组已经遍历完了,此时的j == s12ength
if(j == s12ength) {
//返回第一次出现的位置当然也可以 return i - s12ength;
return i - j;
}
//当匹配失败时
return -1;
}
}