问题背景
有一个字符串
s
t
r
1
=
"
w
h
e
l
l
str1 = "whell
str1="whell
h
e
l
l
o
"
hello"
hello",和一个字符子串
s
t
r
2
=
"
h
e
l
l
o
"
str2 = "hello"
str2="hello"
判断
s
t
r
1
str1
str1中是否含有
s
t
r
2
str2
str2,如果存在,就返回第一次出现的位置,如果没有,则返回
−
1
-1
−1
思路分析
- 将两个字符串转为 c h a r char char数组
- 定义两个变量 i , j i,j i,j遍历 s t r 1 str1 str1和 s t r 2 str2 str2
- 如果两个数组的元素匹配,即 s t r 1 [ i ] = = s t r 2 [ j ] str1[i] == str2[j] str1[i]==str2[j],则 i + + , j + + i++,j++ i++,j++,继续匹配
- 如果两个数组的元素不匹配,即 s t r 1 [ i ] ! = s t r 2 [ j ] , str1[i] != str2[j], str1[i]!=str2[j],则 i = i − j + 1 ; j = 0 , i= i-j+1;j=0, i=i−j+1;j=0,继续匹配。
- 如果两个数组中的任意个索引到达边界则停止匹配;
5.1 s t r 1 str1 str1到达边界:元素遍历完了:匹配成功/未成功
5.1 s t r 2 str2 str2到达边界:元素遍历完了:匹配成功。 - 判断是否匹配成功:检查j是不是到达了
s
t
r
2
str2
str2的边界
如果到达边界 返回 i − j i-j i−j:即字符串出现的初始位置
如果位到达边界,返回 − 1 -1 −1。
可以用遍历的思路
索引 i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
str1 | w | h | e | l | l | h | e | l | l | o |
索引 j | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
str2 | h | e | l | l | o |
第1步:
第2步:
第3步:
第4步:
第5步:
第6步:
第7步:
java代码
package kmp;
public class ViolenceMatch {
public static void main(String[] args) {
// TODO Auto-generated method stub
//测试暴力匹配算法
String str1 = "hello word hello";
String str2 = "word";
int index = violenceMatch(str1,str2);
System.out.println("index="+index);
}
//暴力匹配算法实现
public static int violenceMatch(String str1,String str2){
//将两个字符串转为char数组
char[] s1 = str1.toCharArray();
char[] s2 = str2.toCharArray();
//获取两个char数组的长度
int s1Len = s1.length;
int s2Len = s2.length;
//定义两个索引,分别指向两个数组
int i = 0; //i索引指向s1
int j = 0;//j索引指向s2
//在两个索引范围内移动两个索引
while(i<s1Len && j<s2Len){//保证匹配时,不越界
if(s1[i] == s2[j]){//匹配ok,两个索引都向后移动一位
i++;
j++;
}else{//没有匹配成功
//如果失败,i在上次的初始索引的基础上往后移动一位。
i= i-(j-1);//往后移动一位
j=j-j;
}
}
//判断是否匹配成功//匹配成功,j会移动到数组长度的下一位,即j==s2Len
if(j == s2Len){
return i-j; //返回第一个数组匹配成功的起始索引
}else{
return -1;//没有匹配成功,返回-1
}
}
}