Brute-Force 演算法與KMP演算法
阿新 • • 發佈:2018-12-03
串的模式匹配
串的模式匹配也叫查詢定位,指的是在當前串中尋找模式串的過程。主要的模式匹配演算法有 Brute-Force 演算法 和 KMP 演算法;
Brute-Force 演算法
Brute-Force 演算法從主串的第一個字元開始和模式串的第一個字元進行比較,若相等,則繼續比較後續字元;否則從主串的第二個字元開始重新和模式串進行比較。依次類推,直到模式串的每個字元依次與主串的字元相等,匹配成功;
//從位序號為begin的字元開始搜尋與str相等的子串
public int BF(String str, int begin) throws Exception {
if(str.length()<=curLen&&str!=null&&curLen>0){
int i=begin;
int len=str.length();
while(i<=curLen-len){//從主串的第i個元素開始比較
for(int j=0;j<len;j++){//比較模式串的元素
if(str.charAt(j)!=strValue[j+i]){
i++;
break; //跳出當前迴圈
}
else if(j==len-1){ //len個字元全部匹配成功
return i;
}
}
}
}
return -1;
}
Brute-Force 演算法的實現簡單,但效率非常低。
測試:
public class A {
private char[] strValue;//字元陣列存放串值
private int curLen;//當前串的長度
//構造空串
public A(){
strValue=new char[0];
curLen=0;
}
//以字串常量構造串
public A(String str){
char[] p=str. toCharArray();
strValue=p;
curLen=p.length;
}
//從位序號為begin的字元開始搜尋與str相等的子串
public int BF(String str, int begin) throws Exception {
if(str.length()<=curLen&&str!=null&&curLen>0){
int i=begin;
int len=str.length();
while(i<=curLen-len){//從主串的第i個元素開始比較
for(int j=0;j<len;j++){//比較模式串的元素
if(str.charAt(j)!=strValue[j+i]){
i++;
break; //跳出當前迴圈
}
else if(j==len-1){//len個字元全部匹配成功
return i;
}
}
}
}
return -1;
}
public static void main(String[] args) throws Exception{
A aa =new A("ssdfgasdbababa");
int result = aa.BF("fg", 0);
System.out.println(result); //輸出3
}
}
KMP 演算法
因此我們需要:
- 取得目標字串的匹配值陣列next[];
- 根據next[]陣列實現KMP演算法;
求陣列next[]:
public static int[] kmpnext(String dest){
int[] next = new int[dest.length()];
next[0] = 0;
for(int i = 1,j = 0; i < dest.length(); i++){
while(j > 0 && dest.charAt(j) != dest.charAt(i)){
j = next[j - 1];
}
if(dest.charAt(i) == dest.charAt(j)){
j++;
}
next[i] = j;
}
return next;
}
KMP實現:
public static int kmp(String str, String dest,int[] next){//str文字串 dest 模式串
for(int i = 0, j = 0; i < str.length(); i++){
while(j > 0 && str.charAt(i) != dest.charAt(j)){
j = next[j - 1];
}
if(str.charAt(i) == dest.charAt(j)){
j++;
}
if(j == dest.length()){
return i-j+1;
}
}
return 0;
}
測試:
public static void main(String[] args){
//String a = "ababa"; 輸出9 0 0 1 2 3
// String b = "ssdfgasdbababa";
String a = "dfg"; //輸出2 0 0 0
String b = "ssdfgasdbababa";
int[] next = kmpnext(a);
int res = kmp(b, a,next);
System.out.println(res);
for(int i = 0; i < next.length; i++){
System.out.println(next[i]);
}
}
以上的內容來自51CTO學院的資料結構課程,我只是整理了一下以便日後方便複習,如有侵權我會自行刪除;
原文:http://edu.51cto.com/center/course/lesson/index?id=68078
挺好理解的,講師講的很通熟易懂,想學習的可以去看原版視訊;