串(string)是由零个或多个字符组成的有限序列又名叫字符串。
- 一般地,由n个字符串构成的串记作: S=“a0a1…an-1”(n≥0),其中a_i(1≤i≤n)
- n是个有限的数值
- 串一般记为S是串的名称,用引号括起来的字符序列是串的值
- 可以是字母,数字或其他字符,i就是该字符在串中的位置,串中的字符数目n称为串的长度
在对字符串S做处理时,经常需要取出其中某一连续的片段,称为S的子串(substring)
- 具体地,由串S中起始于位置i的连续k个字符组成的子串记作substr(S,i,k) = “aiai+1…ai+k-1”,0≤i (n,0≤k)
- 前缀 prefix(S,k) = substr(S,0,k);
- 后缀 suffix(S,k) = substr(S,n-k,k)
- 空格串:只包含空格的串。
- 从主串的第一个字符起与子串的第一个字符进行比较,若相等,则继续对字符串进行后续的比较
- 若不相等,则从主串第二个字符起与子串的第一个字符重新比较,以此类推,直到子串中每个字符依次和主串中的一个连续的字符序列相等为止,此时称为匹配成功。
- 如果不能在主串中找到与子串相同的字符序列,则匹配失败。
需要进行回溯操作,否则会错过相等的部分
public static void bruteForce(String parent,String sub){
//成功匹配的位置
int index = -1;
//主串的长度
int pLen = parent.length();
//子串的长度
int sLen = sub.length();
if (pLen= sLen) {
index = i - j;
System.out.println("Successful match,index is:" + index);
} else {// 匹配失败
System.out.println("Match failed.");
}
}
KMP算法
其核心思想是主串不回溯,模式串尽量多向右移动
首先构造next表(next表里存放的是字符串真后缀与真前缀相同的子字符串最大长度):
以ABCDABD为例说明构建next表
P = ABCDABD j = 0, prefix(P, 0) = φ next[0] = -1;//规定如此 P = ABCDABD j = 1, prefix(P, 1) = A 真前缀: φ 真后缀: φ next[1] = 0; P = ABCDABD j = 2, prefix(P, 2) = AB 真前缀: A 真后缀: B next[2] = 0; P = ABCDABD j = 3, prefix(P, 3) = ABC 真前缀: A,AB 真后缀: BC,C next[3] = 0; P = ABCDABD j = 4, prefix(P, 4) = ABCD 真前缀: A,AB,ABC 真后缀: BCD,CD,D next[4] = 0; P = ABCDABD j = 5, prefix(P, 5) = ABCDA 真前缀: A,AB,ABC,ABCD 真后缀: BCDA,CDA,DA,A next[5] = 1; P = ABCDABD j = 6, prefix(P, 6) = ABCDAB 真前缀: A,AB,ABC,ABCD,ABCDA 真后缀: BCDAB,CDAB,DAB,AB,B next[6] = 2; 得出next表为: [-1, 0, 0, 0, 0, 1, 2]代码实现
package string;
public class KMP {
//构建next表
public static int[] buildNext(String sub){
//构建next表就是查找真前缀 == 真后缀的最大长度,以获取模式串尽量多地往右移动
int[] next = new int[sub.length()];
//主串位置
int j = 0;
//子串位置
int t = next[0] = -1;
while (j= sLen) {
index = i - j;
System.out.println("Successful match,index is:" + index);
} else {// 匹配失败
System.out.println("Match failed.");
}
}
}



