描述
Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For example, the text string B is ‘1001110110’ while the pattern string A is ‘11’, you should output 3, because the pattern A appeared at the posit
-
输入
- The first line consist only one integer N, indicates N cases follows. In each case, there are two lines, the first line gives the string A, length (A) <= 10, and the second line gives the string B, length (B) <= 1000. And it is guaranteed that B is always longer than A. 输出
- For each case, output a single line consist a single integer, tells how many times do B appears as a substring of A. 样例输入
-
3 11 1001110110 101 110010010010001 1010 110100010101011
样例输出
-
3 0 3
code
import java.util.Scanner; import java.util.Vector; public class Main { static int result = 0; public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = 2 * sc.nextInt(); Vector<String> strs = new Vector<String>(); while (n-- > 0) { String line = sc.next(); strs.add(line); } for (int i = 0; i < strs.size(); i += 2) { test(strs.get(i + 1), strs.get(i)); System.out.println(result); result = 0; } } // 计算重复的次数 public static void test(String s, String t) { if (s.length() > t.length()) { int sub = KMP_Index(s, t); if (-1 == sub) return; result++; s = s.substring(sub + 1); test(s, t); } } // 获得字符串的next函数值 public static int[] next(char[] t) { int[] next = new int[t.length]; next[0] = -1; int i = 0; int j = -1; while (i < t.length - 1) { if (j == -1 || t[i] == t[j]) { i++; j++; if (t[i] != t[j]) { next[i] = j; } else { next[i] = next[j]; } } else { j = next[j]; } } return next; } // KMP匹配字符串 public static int KMP_Index(char[] s, char[] t) { int[] next = next(t); int i = 0; int j = 0; while (i <= s.length - 1 && j <= t.length - 1) { if (j == -1 || s[i] == t[j]) { i++; j++; } else { j = next[j]; } } if (j < t.length) { return -1; } else return i - t.length; } public static int KMP_Index(String s, String t) { return KMP_Index(s.toCharArray(), t.toCharArray()); } }
分析
kmp算是比较快速的字符串匹配算法,一句话描述就是:如果模式串(t)中首个不匹配字符(下标为j)前面的k个字符和模式串开始的前k个字符如果相同(且t[j] != t[k]),那么被匹配的串(s)向后跳k个字符,再开始比较。