1 問題描述
給定一個n個字符組成的串(稱為文本),一個m(m <= n)的串(稱為模式),從文本中尋找匹配模式的子串。
2 解決方案
2.1 蠻力法
package com.liuzhen.chapterThree; public class BruteForceStringMatch { //根據文本串N,和模式串M,返回第一個匹配模式串的子串在N中的位置 public static int getStringMatch(int[] N , int[] M){ int n = N.length; //文本串的長度 int m = M.length; //模式串的長度 for(int i = 0;i < n-m;i++){ //最后一輪子串匹配的起始位置是n-m,如果大於n-m一定不會出現匹配子串 int j = 0; while(j < m && M[j] == N[i+j]) j = j +1; if(j == m) return i; } return -1; } public static void main(String args[]){ int[] N = {1,2,3,2,4,5,6,7,8,9}; int[] M = {6,7,8}; int position = getStringMatch(N,M); System.out.println("文本串N中第"+position+"位開始,可以尋找一個匹配模式M的子串,該位置字符值為:"+N[position]); } }
運行結果:
文本串N中第6位開始,可以尋找一個匹配模式M的子串,該位置字符值為:6
2.2 KMP模式匹配法
package com.liuzhen.practice; public class Main { //獲取匹配字符串B的next函數值 public int[] getNext(String B) { char[] arrayB = B.toCharArray(); int[] next = new int[arrayB.length + 1]; int j = 0; for(int i = 1;i < arrayB.length;i++) { while(j > 0 && arrayB[i] != arrayB[j]) j = next[j]; if(arrayB[i] == arrayB[j]) j++; next[i + 1] = j; } return next; } //輸出B在A中出現匹配子串所有情況的第一個位置 public void getKMP(String A, String B) { int[] next = getNext(B); char[] arrayA = A.toCharArray(); char[] arrayB = B.toCharArray(); int j = 0; for(int i = 0;i < arrayA.length;i++) { while(j > 0 && arrayA[i] != arrayB[j]) j = next[j]; if(arrayA[i] == arrayB[j]) j++; if(j == arrayB.length) { System.out.println("開始匹配位置:"+(i - j + 1)); j = 0; //重新開始新的匹配檢查 } } return; } public static void main(String[] args) { Main test = new Main(); String A = "bbaabbbbbaabbbbaabb"; String B = "bbbaa"; test.getKMP(A, B); } }
運行結果:
開始匹配位置:6
開始匹配位置:12