字串 求 子串 位置 的 演算法 叫做 模式比對演算法。
模式比對 演算法 有 好多種,比較 常見的 有 暴力 匹配演算法 和 KMP 演算法。暴力匹配演算法 時間 複雜度為O(M*N),KMP 時間複雜度為 O(M+N)。
下面給出兩種演算法的代碼
歡迎指出代碼不足
// KMP.cpp : 定義控制台應用程式的進入點。//求子串問題..#include "stdafx.h"#include <cstring>#include <cstdlib>//暴力匹配演算法,時間複雜度 為 O(m*n)//求在 母串 s 從 第 pos 個位置開始 子串 t的位置static int runTimes = 0;//執行次數...int normal(char * s,char * t,int pos){int sLen = strlen(s);//母串的位置int tLen = strlen(t);//子串的長度int i = pos-1,j = 0;//計算起始值int first = i;//匹配開始的位置runTimes = 0;while (i <sLen && j < tLen){runTimes++;if (s[i] == t[j]) {//相等i++,j++;}else{//不相等,i = 匹配開始的值+1, j = 0i = ++first;j = 0;}}if (j >= tLen){//匹配成功.return first+1;}else{//匹配不成功,返回 -1return -1;}}//普通 求 Nextvoid getNext1(char * t,int len,int * next){next[0] = -1;//初值..int i = 0,j = -1;while (i < len -1){if(j == -1 || t[i] == t[j]){i++,j++;next[i] = j;}else{j = next[j];}}}//求Next 改進void getNext2(char * t,int len,int * next){next[0] = -1;//初值..int i = 0,j = -1;while (i < len -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];}}}//kmp 模式比對法.int kmp(char * s,char * t,int pos,int fun){int sLen = strlen(s);int tLen = strlen(t);int i = pos - 1,j = 0;int * next = (int *) malloc(sizeof(int) * tLen);//next 數組if (fun == 1){getNext1(t,tLen,next);//計算next}else{getNext2(t,tLen,next);//計算next}runTimes = 0;while (i < sLen && j < tLen){runTimes ++;if (j == -1 || s[i] == t[j]){i++,j++;}else{//i值 不回溯,j = next[j]j = next[j];}}free(next);//釋放空間..if (j >= tLen){return i - j + 1;}return -1;}//列印 資訊 //kind , 1: 暴力匹配 2:KMP 3.改進KMPvoid printMsg(char * string,int index,int kind){ if (index != -1){char * point = string + index - 1; char *s = NULL;if (kind == 1){s = "暴力匹配";}else if(kind == 2){s = "kmp匹配";}else{s = "改進kmp匹配";}printf("%s 求得字串為:%s,\t執行次數%d\n",s,point,runTimes); } } int _tmain(int argc, _TCHAR* argv[]){char * string = "abcdefghijklmnsdfdsdfsfdsd"; char * sub = "sdfd"; int index = normal(string,sub,1);printMsg(string,index,1);index = kmp(string,sub,1,1);printMsg(string,index,2);index = kmp(string,sub,1,2);printMsg(string,index,3);string = "0000000001100000000011000000000111000000000001111aa"; sub = "000000000001111"; index = normal(string,sub,1);printMsg(string,index,1);index = kmp(string,sub,1,1);printMsg(string,index,2);index = kmp(string,sub,1,2);printMsg(string,index,3);return 0;}
參考書籍:嚴蔚敏《資料結構。C語言版》