You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
package class36;
|
|
|
|
|
|
|
|
|
|
// 来自美团
|
|
|
|
|
// 给定两个字符串s1和s2
|
|
|
|
|
// 返回在s1中有多少个子串等于s2
|
|
|
|
|
public class Code03_MatchCount {
|
|
|
|
|
|
|
|
|
|
public static int sa(String s1, String s2) {
|
|
|
|
|
if (s1 == null || s2 == null || s1.length() < s2.length()) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
char[] str1 = s1.toCharArray();
|
|
|
|
|
char[] str2 = s2.toCharArray();
|
|
|
|
|
return count(str1, str2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 改写kmp为这道题需要的功能
|
|
|
|
|
public static int count(char[] str1, char[] str2) {
|
|
|
|
|
int x = 0;
|
|
|
|
|
int y = 0;
|
|
|
|
|
int count = 0;
|
|
|
|
|
int[] next = getNextArray(str2);
|
|
|
|
|
while (x < str1.length) {
|
|
|
|
|
if (str1[x] == str2[y]) {
|
|
|
|
|
x++;
|
|
|
|
|
y++;
|
|
|
|
|
if (y == str2.length) {
|
|
|
|
|
count++;
|
|
|
|
|
y = next[y];
|
|
|
|
|
}
|
|
|
|
|
} else if (next[y] == -1) {
|
|
|
|
|
x++;
|
|
|
|
|
} else {
|
|
|
|
|
y = next[y];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// next数组多求一位
|
|
|
|
|
// 比如:str2 = aaaa
|
|
|
|
|
// 那么,next = -1,0,1,2,3
|
|
|
|
|
// 最后一个3表示,终止位置之前的字符串最长前缀和最长后缀的匹配长度
|
|
|
|
|
// 也就是next数组补一位
|
|
|
|
|
public static int[] getNextArray(char[] str2) {
|
|
|
|
|
if (str2.length == 1) {
|
|
|
|
|
return new int[] { -1, 0 };
|
|
|
|
|
}
|
|
|
|
|
int[] next = new int[str2.length + 1];
|
|
|
|
|
next[0] = -1;
|
|
|
|
|
next[1] = 0;
|
|
|
|
|
int i = 2;
|
|
|
|
|
int cn = 0;
|
|
|
|
|
while (i < next.length) {
|
|
|
|
|
if (str2[i - 1] == str2[cn]) {
|
|
|
|
|
next[i++] = ++cn;
|
|
|
|
|
} else if (cn > 0) {
|
|
|
|
|
cn = next[cn];
|
|
|
|
|
} else {
|
|
|
|
|
next[i++] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|