串的模式匹配算法一

最近,经常使用String的indexOf()方法,于是很想琢磨一下它的内部实现机制,如果我我来实现的话,会采用什么办法?
首先我想到的是使用简单模式匹配算法,思路很清楚,但是时间复杂度很高 最坏的情况是O(n*m)(n是主串的长度,m是模式串的长度).
后来想到KMP算法很强悍,时间复杂度好像是线性的,不过杯具的是我对kmp算法完全没有印象。花了点时间看了会书,写了段代码,总算明白kmp算法了。
话不多说,直接贴代码:
package chapterFour;

/**
*
* @author wanglianqin
*
* 2010-11-30
*/
public class KMP {

private int[] next;

// 求模式串pat的next函数值并存入数组next
public void get_next(char[] pat) {
int lenPat = pat.length - 1;

next = new int[lenPat + 1];
next[0] = lenPat;
next[1] = 0;
int j = 0;
int i = 1;
while (i < lenPat) {

if ((pat[i] == pat[j])) {
++i;
++j;
next[i] = j;

} else if (j == 0) {
j++;
i++;
next[i] = 1;

} else {
j = next[j];

}
}

}

// 简单模式匹配算法
public int index_simple(char[] s, char[] pat, int pos) {

int i = pos;
int j = 1;
int s_length = s.length - 1;
int pat_length = pat.length - 1;
while (i <= s_length && j <= pat_length) {
if (s[i] == pat[j]) {
i++;
j++;
} else {

i = i - j + 2;
j = 1;
}
}

if (j > pat_length) {
return i - pat_length;
} else {

return 0;
}
}

//kmp模式匹配算法
public int index_kmp(char[] s, char[] pat, int pos) {

int i = pos;
int j = 1;
int s_length = s.length - 1;
int pat_length = pat.length - 1;
while (i <= s_length && j <= pat_length) {
if (j==0||s[i] == pat[j]) {
i++;
j++;
} else {

j=next[j];
}
}

if (j > pat_length) {
return i - pat_length;
} else {

return 0;
}
}



public static void main(String[] args) {
KMP kmp = new KMP();
char[] pat = new char[] { '5', 'a', 'b', 'c', 'a', 'c' };
kmp.get_next(pat);
for (int i : kmp.next) {
System.out.println(i);
}

System.out.println("--------简单模式匹配算法--------");

char[] s = new char[] { '8', 'a', 'b', 'a', 'b', 'c', 'a', 'b', 'c',
'a', 'c', 'b', 'a', 'b' };

System.out.println(kmp.index_simple(s, pat, 3));

System.out.println("--------kmp算法--------");



System.out.println(kmp.index_kmp(s, pat, 3));
}
}

后来我测试了一下,发现简单模式匹配算法和Kmp算法效率差不多,可能是m和n的值都小的原因。
再看看严老师的书,明白了“简单模式匹配算法的时间复杂度是O(m*n),但在一般情况下,其实际的执行时间近似于O(m+n),因此至今仍被采用,KMp算法仅当模式和主串之间存在许多部分匹配的情况下才显得比它好。”。

你可能感兴趣的:(算法基础,算法,J#,C,C++,C#)