1. 程式人生 > >C/C++——樸素的模式匹配演算法和KMP模式匹配演算法

C/C++——樸素的模式匹配演算法和KMP模式匹配演算法

樸素的模式匹配演算法

其實就是一個一個往下匹配,沒有任何優化,在好的情況下時間複雜度為O(n+m),在最求的情況下時間複雜度為O((n-m+1)*m)。
程式碼實現:

//在主串s中找子串t,若找到返回字串在主串中的索引;若沒找到返回-1
#include <iostream>
#include <string>

using namespace std;

int Index(string s, string t){
    int lens = s.length();//計算串s、t的長度
    int lent = t.length();
    int i = 0
; int j = 0; while (i < lens&&j < lent){//如果i、j都各自小於lens和lent if (t[j] == s[i]){//如果子串的t[j]和主串的s[i]相等 ++i;//各自索引都自增 ++j; } else{//否則,主串的索引比剛開始後移一個;子串的索引變為0 i = i - j + 1; j = 0; } } if (j == lent){//如果最j和lent的大小一樣,證明找到了,返回子串在主串中的索引
return i - lent; } else{//否則返回-1 return -1; } } int main(){ string s = "goodgoogle"; string t = "google"; int pos = Index(s, t); if (pos != -1){ cout << "find " << t << " at the index " << pos << " of " << s << endl; } else
{ cout << "can't find " << t << " in " << s << endl; } return 0; }

KMP模式匹配演算法

先對子串t進行next判斷,得到一個next陣列,再進行比較。時間複雜度為O(n+m)
程式碼實現:

//在主串s中找子串t,若找到返回字串在主串中的索引;若沒找到返回-1
#include <iostream>
#include <string>

using namespace std;

void get_next(string t, int *next);
int Index_KMP(string s, string t);

int main(){
    string s = "ababadeababaaabadf";
    string t = "ababaaaba";
    int pos = Index_KMP(s, t);
    if (pos != -1){
        cout << "find " << t << " at the index " << pos << " of " << s << endl;
    }
    else{
        cout << "can't find " << t << " in " << s << endl;
    }

    return 0;
}

int Index_KMP(string s, string t){
    int lens = s.length();
    int lent = t.length();
    int *next = new int[lent];
    get_next(t, next); //對子串t作分析,得到next陣列
    //cout << "next: ";    //輸出next測試而已
    //for (int i = 0; i < lent; ++i){
    //  cout << next[i];
    //}
    //cout << endl;
    int i = 0;
    int j = 0;
    while (i < lens&&j < lent){//兩字母相等則繼續,與樸素演算法增加了j==0的判斷
        if (j == 0 || t[j] == s[i]){
            ++i;
            ++j;
        }
        else{
            j = next[j-1];//j退回合適位置,i值不變
        }
    }
    if (j == lent){//如果最j和lent的大小一樣,證明找到了,返回子串在主串中的索引
        return i - lent;
    }
    else{//否則返回-1
        return -1;
    }
}

void get_next(string t, int *next){
    int lent = t.length();
    int i = 0;
    int j = 0;
    next[0] = 0;
    while (i < lent){//i小於t的長度
        if (j == 0 || t[i] == t[j - 1]){//t[i]表示字尾的單個字元
            ++i;                      //t[j]表示字首的單個字元
            ++j;
            next[i] = j;
        }
        else{
            j = next[j - 1];   //若字元不相同,則j值回溯
        }
    }
}

相關推薦

C/C++——樸素模式匹配演算法KMP模式匹配演算法

樸素的模式匹配演算法 其實就是一個一個往下匹配,沒有任何優化,在好的情況下時間複雜度為O(n+m),在最求的情況下時間複雜度為O((n-m+1)*m)。 程式碼實現: //在主串s中找子串t,若找

串的樸素演算法KMP模式匹配演算法

串的樸素演算法和KMP模式匹配演算法   串的樸素演算法 (BF演算法又稱暴力搜尋):首先待匹配串與模式串首先左對齊,然後從左向右開始逐個進行匹配,如果出現失配情況,則從待匹配串下一個字元開始進行匹配,直到模式串匹配成功。   例如:   &nb

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

串的模式匹配演算法 子串的定位操作通常稱為串的 模式匹配,其中T稱為 模式串。 一般的求子串位置的定位函式(Brute Force) 我寫java的程式碼是這樣的 int index(String S,String T,int pos){

字串模式匹配中BF演算法KMP演算法的java實現

關於BF演算法和KMP演算法的具體解釋,文章【部落格地址】:KMP字串匹配演算法與next陣列中有推薦部落格的具體地址,可以在這些部落格中找到詳細的解釋。 以下只有具體的java程式碼實現: BF演

資料結構實驗-C語言-二叉樹的建立,前、中、後序遍歷的遞迴演算法和非遞迴演算法,求葉子結點數目,求二叉樹深度,判斷二叉樹是否相似,求二叉樹左右子樹互換,二叉樹層序遍歷的演算法,判斷二叉樹是否是完全二叉樹

1.實驗目的 熟練掌握二叉樹的二叉連結串列儲存結構的C語言實現。掌握二叉樹的基本操作-前序、中序、後序遍歷二叉樹的三種方法。瞭解非遞迴遍歷過程中“棧”的作用和狀態,而且能靈活運用遍歷演算法實現二叉樹的其它操作。 2.實驗內容 (1)二叉樹的二叉連結串列的建立 (2)二叉樹的前、中、後

java實現Brute-ForceKMP模式匹配

Brute-Force模式匹配演算法 從主串第start(i=start)個字元起,與模式串t的第一個字元(j=0)開始比較。 若相等,則繼續比較後面字元(i++,j++) 若不相等,則從主串第二個字元起重新和模式串t比較(i=i-j+1,j=0) 若都匹配成功,則返回模式串t第

BFKMP字串匹配演算法

我們平時在使用 java 程式設計中,判斷一個字串是否包含另一個字串可以使用 String 自帶的方法或者正則表示式,但是inde

字串匹配-BF演算法KMP演算法

宣告:圖片及內容基於https://www.bilibili.com/video/av95949609 BF演算法 原理分析 Brute Force 暴力演算法 用來在主串中查詢模式串是否存以及出現位置     核心就是回溯 如果模式串下標 j 始終沒有到達'\0'則沒有找到

BF演算法KMP演算法對比

BF演算法和KMP演算法     子串的定位操作通常被稱作串的模式匹配,所謂的模式匹配即從較長的字串S(主串)的pos位置處開始尋找字串P(模式串)首次出現的位置,模式匹配演算法經典的有BF演算法和KMP演算法。 1、BF演算法     BF演算法的思想是從主串的第pos

模式對話方塊模式對話方塊、accept()函式、exec()函式,Accepted訊號區別

一.非模式對話方塊   非模式對話方塊是和同一個程式中其它視窗操作無關的對話方塊。在字處理軟體中查詢和替換對話方塊通常是非模式的來允許同時與應用程式主視窗和對話方塊進行互動。呼叫show()來顯示非模式對話方塊。show()立即返回,這樣呼叫程式碼中的控制流將會繼續。   非模式

Spring 5 設計模式 - 使用代理裝飾模式的Spring AOP

Spring 5 設計模式 - 使用代理和裝飾模式的Spring AOP Spring中的代理模式 什麼是AOP AOP要解決的問題 程式碼糾纏 程式碼分散 解決 AOP的核心術語

實現銀行家演算法先進先出演算法_從檔案裡讀資料

作業系統考試老師出了兩道題,一個是先進先出,另一個是銀行家演算法,題目如下 1.請使用FCFS演算法模擬程序排程。假設系統有n (n>=2) 個程序,給定程序的到達時間以及需要執行的時間長短,給出相應的執行順序。資料以檔案方式給出,檔名為data.fcfs,格式為: 檔案共n(N1…Nn)

直線生成演算法的實現:分別利用DDA演算法、中點Bresenham演算法改進的Bresenham演算法掃描轉換直線段P1P2

直線生成演算法的實現:分別利用DDA演算法、中點Bresenham演算法和改進的Bresenham演算法掃描轉換直線段P1P2,其中P1為(0, 0), P2為(8, 6)。   // fhk.cpp : 定義控制檯應用程式的入口點。 // #include <iost

垃圾回收之判斷物件否需要被回收(根搜尋演算法引用搜索演算法

根搜尋演算法(JAVA的虛擬機器用的是這個) 可以參考這個 http://blog.csdn.net/qq_15022971/article/details/79162126 引用搜索演算法:是常被初學JAVA者誤解,java的垃圾回收在判斷一個物件是否為可以被回收的物件時,常被誤以為

瞭解 kmeans演算法譜聚類演算法

譜聚類演算法 不過真正要直觀地理解譜聚類,其實應該從物理的簡正模振動的角度來理解。你可以認為每兩個點之間都有一個彈簧連著,把兩個點之間的相似度理解為它們的彈簧係數,每個特徵向量就是這個系統的運動

資料探勘18種候選演算法十大經典演算法

       國際權威的學術組織the IEEE International Conference on Data Mining (ICDM) 2006(香港召開)年12月評選出了資料探勘領域的十大經典演算法。不僅僅是選中的十大演算法,其實參加評選的18種演算法,實際上隨便

作業系統: 最佳適配演算法鄰近適配演算法的模擬實現(記憶體分配演算法

實現動態分割槽的分配演算法。 (1) 最佳適配演算法:選擇記憶體空閒塊中最適合程序大小的塊分配。 (2) 鄰近適配演算法:從上一次分配的地址開始查詢符合要求的塊,所查詢到的第一個滿足要求的空閒塊就分配給程序。 模擬新增程序的時候,假定記憶體是一塊完整的空閒區,對於演算法(1

斐波那契數列遞迴演算法非遞迴演算法以及其時間複雜度分析

1、在學習資料結構這門課的過程中,發現斐波那契數列的遞迴演算法以及非遞迴演算法,以及其時間複雜度分析是一個小難點。所以特別總結一下。 斐波那契數列的表示式: Fibonacci數列簡介: F(1)=

Internet流量監管機制之漏桶演算法令牌桶演算法

        漏桶演算法和令牌桶演算法都是為了限制應用無限制的向網路注入流量而設定的演算法。兩者看似區別不大,但是如果仔細來看,是有區別的:漏桶演算法只能把應用的輸出速率限定在一個固定的速度,但是令牌桶除了在把總的輸出速率限制在一定範圍內,還能容忍一定時間的高速率突發流量

JVM--18 【垃圾回收演算法】標記-整理演算法分代收集演算法

         前言: 複製收集演算法在物件存活率較高時就要進行大量的複製操作,效率將會變低。更關鍵的是,如果不想浪費50%的空間,就需要額外的空間進行分配擔保,以應對被使用的記憶體中所有物件都100%存活的極端情況,所以在老年代一般不能直接選用複製演算法。  標記-整