簡體   English   中英

KMP字符串匹配算法:輔助數組輸出

[英]KMP string matching algorithm:Auxillary array output

這是我對KMP字符串匹配算法的實現 當我檢查pi數組時,它存儲0、1、2、3、4、5、6。 但是根據算法書籍,它應該是0,0,1,2,3,0,1。 我的代碼也給出正確的結果。我不明白為什么會這樣,還是我做錯了什么? 如果是這樣,請糾正我。

謝謝。

#include<iostream>
#include<string>
#include<string.h>

using namespace std;

int* ComputePrefix(char P[])
{
    size_t m = strlen(P);
    int *pi = new int[m];
    pi[0] = 0;
    int k = 0;

    for(int q =0; q < m; q++)
    {
        if( k > 0 && P[k+1] != P[q])
            k = pi[k];

        if( P[k+1] == P[q])
            {
                pi[q] = k;
                k = k + 1;
            }
            pi[q]=k;
    }

    return (pi);
}

void KMP_Matcher(char T[], char P[])
{

    size_t n = strlen(T);
    size_t m = strlen(P);

    int *pi = new int[m];
    pi = ComputePrefix(P);

    cout<<endl;


    int q =0;
    for (int i = 0; i <= n; i++)
    {
        if( q > 0 && P[q] != T[i] )
        {
            q = pi[q - 1];
        }


        else if( P[q] == T[i])
        {


            if( q == m-1)
            {
                cout<<"Shift occurs at : "<< i-q <<endl;
                q = pi[q];
            }
            else q = q + 1;
        }

        else q++;
    }
}


int main()
{
    char T[] = "abababacaba";
    char P[] = "ababaca";

    KMP_Matcher(T,P);
    return 0;
}

您的跳轉表構造函數根本不會檢查指針的前綴。 我們希望能夠針對針中的每個位置查找導致(但不包括)該位置的針的盡可能長的適當前綴的長度,而不是從needle[0]開始的完整前綴只是不匹配; 這是尋找下一場比賽我們必須回溯的距離。 因此,跳轉表中的每個條目(例如, table[i] )恰好是針的最長可能適當前綴的長度,該長度也是以needle[i - 1]結尾的子串的前綴。

跳轉表中的前兩個條目分別為-1和0,因為a)模式開頭的不匹配不會觸發回溯(換句話說,長度為零的前綴不能有任何適當的前綴或后綴),並且b)空字符串被認為長度為0。

有關更多詳細信息,請參閱Wikipedia或算法教科書。

完成以上操作的代碼是:

int *build_jump_table(const char * target)
{
    if(!target)
        return NULL;
    int *table = new int[strlen(target) + 1];
    if(!table)
        return NULL;
    table[0] = -1; /* unused by the matcher, just used here */

    for(int i = 0; target[i] != '\0'; i++) {
        table[i+1] = table[i] + 1;
        while(table[i+1] > 0 && target[i] != target[table[i+1] - 1]) {
            table[i + 1] = table[table[i + 1] - 1] + 1;
        }
    }
    return table;
}

這非常冗長,當您了解跳轉表背后的概念時,可以進行很多簡化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM