KMP算法

//KMP模式匹配算法
void get_next(string T, int* next)   //計算出當前要匹配的串next數組
{
    int i, j;
    i = 1;
    j = 0;
    next[1] = 0;
    while (i < T[0])   //此處T[0]表示串T的長度
    {
        if (j == 0 || T[i] == T[j])   //T[i]表示後綴的單個字符,T[j]表示前綴的單個字符
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else
            j = next[j];  //若字符不相同,則j值回溯
    }
}
int Index_KMP(string S, string T, int pos)
{
    int i = pos;  //i用於主串S中當前位置下標,若pos不爲1,則從pos位置開始匹配
    int j = 1;  //j用於子串T中當前位置下標值
    int next[255];  //定義一個next數組
    get_next(T, next);   //對串T作分析,得到next數組
    while (i <= S[0] && j <= T[0])  //若i小於S長度且j小於T的長度時循環
    {
        if (j == 0 || S[i] == T[j])  //兩字母相等則繼續,與樸素算法增加了j=0判斷
        {
            ++i;
            ++j;
        }
        else  //指針後退重新開始匹配
        {
            j = next[j];  //j退回合適的位置,i值不變
        }
    }
    if (j > T[0])
        return i - T[0];
    else
        return 0;
}

//KMP模式匹配改進算法
void get_nextval(string T, int* nextval)   //計算出當前要匹配的串next數組
{
    int i, j;
    i = 1;
    j = 0;
    nextval[1] = 0;
    while (i < T[0])   //此處T[0]表示串T的長度
    {
        if (j == 0 || T[i] == T[j])   //T[i]表示後綴的單個字符,T[j]表示前綴的單個字符
        {
            ++i;
            ++j;
            if (T[i] != T[j])  //若當前字符與前綴字符不同
                nextval[i] = j;  //則當前的j爲nextval在i位置的值
            else
                nextval[i] = nextval[j];  //如果與前綴字符相同,則將前綴字符的nextval值賦給nextval在i位置的值
        }
        else
            j = nextval[j];  //若字符不相同,則j值回溯
    }
}
int Index_KMP(string S, string T, int pos)
{
    int i = pos;  //i用於主串S中當前位置下標,若pos不爲1,則從pos位置開始匹配
    int j = 1;  //j用於子串T中當前位置下標值
    int next[255];  //定義一個next數組
    get_nextval(T, next);   //對串T作分析,得到next數組
    while (i <= S[0] && j <= T[0])  //若i小於S長度且j小於T的長度時循環
    {
        if (j == 0 || S[i] == T[j])  //兩字母相等則繼續,與樸素算法增加了j=0判斷
        {
            ++i;
            ++j;
        }
        else  //指針後退重新開始匹配
        {
            j = next[j];  //j退回合適的位置,i值不變
        }
    }
    if (j > T[0])
        return i - T[0];
    else
        return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章