字符串匹配相关算法

今天无意间碰到了需要写子字符串匹配得算法,由于以前一直对字符串得KMP算法不太了解,所以今天趁着这个机会正好记录下这三种算法的差异:

  1. JavaApi实现
  2. 朴素字符串匹配算法
  3. KMP算法

Java的API实现子字符串查找:

在Java的String类里面有一个方法是indexof(str,index), 这个类的话是可以从一个字符串的指定位置查出是否包含子字符串,若不包含则返回的是-1,若包含的话则返回的是该子字符串在字符串中的索引位置。 那么这个算法是什么原理呢,这个算法的原理就是indexof会返回匹配到的字符串的索引,那么当这个算法匹配到了一个之后获取返回的索引,然后再加上字符串的长度,最后再在剩下的字符串里面匹配,便会得出所有的字符串个数。

1
2
3
4
5
6
7
8
9
10
11
public void test(){
String findText= "abcd";
String srcText ="mabcdfafasabcdfa";
int count = 0;
int index = 0;
while ((index = srcText.indexOf(findText, index)) != -1) {
index = index + findText.length();
count++;
}
System.out.println(count);
}
阅读更多

leetcode的一道字符串题目:最长不重复的子字符串长度

找出最长的不重复的子字符串

首先一拿到这个题目的时候想到利用set集合来存储子字符串,当发现含有重复的字符的时候就将这个set清零。这个做法有一个明显的缺点就是当子字符串中的某一个字符和后面的重复的话,那么后面不行同的也会被清楚:例如dfvfab,在这个里面vfab应该是最短的子字符串,但是这时候这个方法会输出错误的值。

思路:

自己想不到解法之后就参考了Solution2,这个方法想了下也挺好的,遂记录下:
该方法是设置两个游标,一个在前,一个在后(定义为i,j),当前面的一个发现在set集合中含有重复的字符,那此时停止i,然后j自增,当发现在set集合中已经将重复的那个字符剔除之后,此时在i自增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public int lengthOfLongestSubstring(String s) {
//错误的思路,以为存入set就可以
// if (s == null || s.length() == 0){
// return 0;
// }
// Set<Character> set =new HashSet<>();
// int max=0;
// for (int i =0 ;i< s.length() ;i++){
// char c = s.charAt(i);
// if (set.contains(c)){
// set.clear();
// }
// set.add(c);
// if (set.size() > max){
// max = set.size();
// }
// }
// return max;
if(s == null || s.length() ==0){
return 0;
}
Set<Character> set =new HashSet<>();
int i=0,j=0,result=0,n=s.length();
while(i < n && j <n){
if(!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
result=Math.max(result,j-i);
}else{
set.remove(s.charAt(i++));
}
}
return result;
}
阅读更多