1. 程式人生 > >[演算法]兩種字串匹配演算法(索引法,KMP演算法)對比,C語言實現

[演算法]兩種字串匹配演算法(索引法,KMP演算法)對比,C語言實現

今天做了個一個簡單的字元對比程式,功能是實現從A串刪除包含B最多的字元的操作,比如A=“aaaaabbbbbbabababa” B=“aaccbaab”,應當刪除“aab”的,不是aa,相信知道搜尋引擎的朋友肯定是知道的吧,這種演算法主要用於去除頁面中無效的關鍵字,來減少收錄的計算消耗的一種方法,好了,具體演算法明天拿出來吧,不過今天要講的是兩種比較常用的字串匹配演算法,KMP演算法,索引法



KMP演算法 是Knuth, Morris, Pratt三位前人提出的字串快速匹配演算法,簡稱KMP演算法,典的演算法了,還有以後發展的BM 和AB-BM演算法,別急啊,這個下次再講,最近是沒時間寫部落格了,原理很簡單,就是使用了額外的數值記錄索引匹配的次數,然後根據這個結果進行結果計算的方法,不知道?可以參閱

http://www.chinaitpower.com/A/2003-01-04/45995.html





索引法,就數最簡單的字串的匹配演算法,原理就是,一個一個試,找到第一個以後,再看是否匹配第二個了,一直到字串末尾,很經典的演算法。



下面我們作個簡單對比,看程式碼:





#include "stdio.h"

#include "string.h"

#include "stdlib.h"

/*getnext*/

void getNext(char p[],int next[]){

int i, j, slen;

slen = strlen(p);

i = 0;

j = -1;

next[0] = -1;

while(i < slen br>
if((j == -1) || (p[i] == p[j])){

i++;

j++;

next[i] = j;

}/*if*/

else{

j = next[j];

}/*else*/

}/*while*/

}/*get_next*/



int kmp(char s[], char p[], int pos, int next[]) {

/*KMP演算法*/

int i, j, slen, plen;

i = pos;

j = 0;

slen = strlen(s);

plen = strlen(p);

while((i < slen j plenbr>
if((j == -1) || (s[i] == p[j])){

i++;

j++;

}

else

{

j = next[j];

}

}/*while*/

if(j >= plen) {

return (i-plen);

}/*if*/

else {

return -1;

}/*else*/

}/*kmp*/



int index(char s[], char p[], int pos){

/*索引匹配法*/

int i, j, slen, plen;

i = pos;

j = 0;

slen = strlen(s);

plen = strlen(p);

while((i < slen j plenbr>
if((s[i] == p[j])){

i++;

j++;

}/*if*/

else{

i = i-j+1;

j = 0;

}/*else*/

}/*while*/

if(j >= plen) {

return (i-plen);

}

else {

return -1;

}

}/*index*/



void main(){

char s[] = "acbaabcaacabaabaabcacaabc"; /*測試字串*/

char p[] = "abaabca";

int next[50];

getNext(p, next);

printf("found index at %dn", kmp(s, p, 0, next));

printf("found index at %dn", index(s, p, 0));

}/*main*/





KMP演算法是kmp()這個函式,INDEX演算法是index()函式,相信諸位看出來了吧,KMP要多一個計算陣列的,這也是精髓所在,也是效率所在,提高了一個數量級,諸位知道這樣提高效率的結果了吧,不過,最壞的情況可能要浪費N多的空間了,好了,演算法提供完,演算法部分大家要是不懂的話,可以直接留言,或者跟我聯絡



附:來自網路的KMP匹配演算法C++實現演算法, 源自http://www.chinaitpower.com/A/2003-01-04/45995.html,作者莫怪,借用一下給大家參考,個人比較喜歡純C,C++最近不怎麼使用了



KMP演算法查詢串S中含串P的個數count

#include

#include

#include

using namespace std;



inline void NEXT(const string& T,vector& next)

{

//按模式串生成vector,next(T.size())

next[0]=-1;

for(int i=1;i

int j=next[i-1];

while(T[i]!=T[j+1]&& j>=0 )

j=next[j] ; //遞推計算

if(T[i]==T[j+1])next[i]=j+1;

else next[i]=0; //

}

}

inline string::size_type COUNT_KMP(const string& S,

const string& T)

{

//利用模式串T的next函式求T在主串S中的個數count的KMP演算法

//其中T非空,

vector next(T.size());

NEXT(T,next);

string::size_type index,count=0;

for(index=0;index

int pos=0;

string::size_type iter=index;

while(pos

if(S[iter]==T[pos]){

++iter;++pos;

}

else{

if(pos==0)++iter;

else pos=next[pos-1]+1;

}

}//while end

if(pos==T.size()&&(iter-index)==T.size())++count;

} //for end

return count;

}

int main(int argc, char *argv[])

{

string S="abaabcacabaabcacabaabcacabaabcacabaabcac";

string T="ab";

string::size_type count=COUNT_KMP(S,T);

cout<<


system("PAUSE");

return 0;

}


--------------------------------------------------------------------------------------
- 版權宣告:
- 如在本頁面內無特別說明,本文內容均為[李大仁部落格]原創,本文版權歸[李大仁部落格]所有。
- 歡迎轉載,轉載請務必在文章頁面明顯位置提供原文連結並註明出處。歡迎您在轉載本文時保留本段宣告。
- 文章標題:C語言實現的兩種字串匹配演算法包括索引法,KMP演算法
- 獨立部落格:李大仁部落格
- 永久連結:http://www.lidaren.com/archives/226
--------------------------------------------------------------------------------------
以上內容由部落格自動釋出工具自動釋出,最終顯示內容和效果會與原文內容有所偏差,敬請諒解。

相關推薦

[演算法]字串匹配演算法索引KMP演算法對比C語言實現

今天做了個一個簡單的字元對比程式,功能是實現從A串刪除包含B最多的字元的操作,比如A=“aaaaabbbbbbabababa” B=“aaccbaab”,應當刪除“aab”的,不是aa,相信知道搜尋引擎的朋友肯定是知道的吧,這種演算法主要用於去除頁面中無效的關鍵字,來減少收錄的計算消耗的一種方法,好了,具體演

Spark中yarn模式提交任務方式yarn-client與yarn-cluster

Spark可以和Yarn整合,將Application提交到Yarn上執行,和StandAlone提交模式一樣,Yarn也有兩種提交任務的方式。 1.yarn-client提交任務方式 配置 在client節點配置中spark-en

二叉樹給出遍歷序列含中序遍歷建立一顆先序遍歷二叉樹

#include <iostream> #include <cstdio> #include <queue> #include <stack> #include <cstring> using namespace

數據結構基礎1--數組C語言實現--動態內存分配

ins post cli itl ini sem pri 應該 insert 數據結構基礎(1)--數組C語言實現--動態內存分配 基本思想:數組是最常用的數據結構,在內存中連續存儲,可以靜態初始化(int a[2]={1,2}),可以動態初始化 malloc()。

Brute-Force模式匹配演算法實現方式

1. public static int indexOf(String mainStr,String subString,int start) { if((mainStr.length()<subString.length()) || mainStr==null || subStr

字串匹配問題BF演算法KMP演算法

問題: 給定兩個字串S和T,在主串S中查詢子串T的過程稱為串匹配,T稱為模式。 BF演算法(樸素模式匹配): BF演算法思想:         就是將目標串S的第一個字元與模式串T的第一個字元進行匹配,若相等,則繼續比較S的第二個字元和T的第二個字元;若不相等,則比較

m選n組合的演算法C語言實現

原問題:  Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. 1. 遞迴演算法 即首先選擇n,然後遞迴地從剩下的1...n-1選擇k-1

c語言實現排序的演算法冒泡選擇

寫下來以記錄自己學習過程中遇到的一些問題 1.利用隨機函式產生10個20以內的整數存於陣列中 (1) 按升序輸出排序後的結果(排序可採用冒泡) (2) 按降序輸出排序後的結果(選擇排序方法) 將問題分塊: 10個隨機數的生成 氣泡排序 選擇排序 (1)對於第

OpenCV3.4立體匹配演算法效果對比

typedef cv::Point_<short> Point2s; template <typename T> void filterSpecklesImpl(cv::Mat& img, int newVal, int maxSpeckleSize, int maxDiff

最短路徑測地距離演算法——Dijkstra和Floyd

     從某頂點出發,沿圖的邊到達另一頂點所經過的路徑中,各邊上權值之和最小的一條路徑叫做最短路徑。解決最短路的問題有以下演算法,Dijkstra演算法,Bellman-Ford演算法,Floyd演算法和SPFA演算法等。 最短路徑問題是圖論研究中的一個經典演算法問題,旨

leetcode 214 Shortest Palindrome kmp演算法 字首字尾字串匹配

0 leetcode 214. Shortest Palindrome  本題的描述是一個串前方加上一些字串,使其成為一個迴文串。 形式類似於(新增部分)(迴文部分)(其餘部分),所以我們的目標就是將其迴文部分求出來,或者把他的長度求出來。 如果用暴力解法,那麼問題就變成

字串匹配的RabinKarp演算法c語言實現

</pre><pre name="code" class="cpp">#include<string.h> int check( char *s1,char *s2,int n ); int main() { char s1[10000],s2[1000000]

方法實現Python二分查詢演算法 方法實現Python二分查詢演算法

兩種方法實現Python二分查詢演算法   一. ? 1 2

資料結構與演算法之美-字串匹配(上)

BF (Brute Force) 暴力/樸素匹配演算法 主串和模式串 我們在字串 A 中查詢字串 B,那字串 A 就是主串,字串 B 就是模式串。 我們把主串的長度記作 n,模式串的長度記作 m。因為我們是在主串中查詢模式串,所以 n>m。 BF演算法思想 在主串中,檢查起始位置分別

c語言實現fcfs,rr_1,spn,srt4排程演算法無資料結構

在網上找的程式碼都很複雜,所以我寫了一個簡單的程式,不涉及任何資料結構,純演算法實現 先科普一下四種演算法的含義(個人理解): FCFS:非剝奪式,意思很明顯,先到達就先執行 RR_1:輪轉排程演算法,時間片為1,在當前時間點或之前到達的,按照順序一個程式執行一次 SPN

演算法--方法實現一個Add函式個整數相加但是不能使用+、-、*、/等四則運算子。

方法一:(網上都解釋的很好 這裡就不贅述了) int Add1(int num1,int num2) { int sum, carry; do { //因為位運算加法,0+1=1,1+0=1,0+0=0,1+1=0

常用的排序演算法c語言實現

概述 最近重新回顧了一下資料結構和演算法的一些基本知識,對幾種排序演算法有了更多的理解,也趁此機會通過部落格做一個總結。 1.選擇排序-簡單選擇排序 選擇排序是最簡單的一種基於O(n2)時間複雜度的排序演算法,基本思想是從i=0位置開始到i=n-1

排序演算法--選擇排序

    選擇排序是一種以重複選擇為思想的排序演算法.其中直接選擇排序是最簡單的一種. 直接選擇排序: 演算法:     假設有一個A[n]的陣列,首先找到最小的元素,將其儲存在A[1]中,然後找到剩下的n - 1個元素中的最小元素,放在A[2]中,重複此過程直到找到第二大的元

整型陣列處理演算法十四不用庫函式C語言實現將一整型數轉換成字串

不用庫函式,用C語言實現將一整型數轉換成字串,如:int a=123456,轉換成"123456"。 如題,要求將一整型數轉換為字串。這裡要考慮的是整型數可能是負數、正數和0。 實現如下: char

串的模式匹配BF演算法KMP演算法

        第一位的next值為0,第二位的next值為1,後面求解每一位的next值時,根據前一位進行比較。首先將前一位與其next值對應的內容進行比較,如果相等,則該位的next值就是前一位的next值加上1;如果不等,向前繼續尋找next值對應的內容來與前一位進行比較,直到找到某個位上內容的next