串+KMP

字符串

串的存儲(chǔ)結(jié)構(gòu)

1.定長(zhǎng)順序存儲(chǔ)表示
用一組地址連續(xù)的存儲(chǔ)單元

#define MAXLEN 255
typedef struct{
    char ch[MAXLEN];
    int length;
}SString;

2.堆分配存儲(chǔ)表示
仍以一組地址連續(xù)的存儲(chǔ)單元存放,但存儲(chǔ)空間是在程序執(zhí)行過(guò)程中動(dòng)態(tài)分配的

typedef struct{
    char *ch;
    int length;
}HString;

C語(yǔ)言中存在一個(gè)稱(chēng)為堆的自由存儲(chǔ)區(qū),并用malloc()和free()函數(shù)來(lái)完成動(dòng)態(tài)存儲(chǔ)管理
上述兩種方式通常為高級(jí)程序設(shè)計(jì)語(yǔ)言采用
3.塊鏈存儲(chǔ)表示
采用鏈表方式存儲(chǔ)串值
在具體實(shí)現(xiàn)時(shí)每個(gè)結(jié)點(diǎn)即可以存放一個(gè)字符,也可以存放多個(gè)字符。每個(gè)結(jié)點(diǎn)稱(chēng)為塊,整個(gè)鏈表稱(chēng)為塊鏈結(jié)構(gòu)。


串的基本操作

StrAssign(&T, chars) "賦值操作,把串T賦值為chars"
StrCopy(&T, S)
StrEmoty(S) "判空"
StrCompare(S,T)
StrLength(S)
SubString(&Sub, S, pos, len) "求子串,用Sub返回S的第pos個(gè)字符起長(zhǎng)度為len的子串"
Concat(&T, S1, S2) "聯(lián)接"
Index(S, T, pos) "定位子串T,第pos個(gè)字符之后第一次出現(xiàn)的位置"
Replace(&S, T, V) "替換子串"
StrInsert(&S, pos, len) "插入子串"
StrDelete(&S, pos, len)
ClearString(&S)
DestroryString(&S)

串的模式匹配

子串的定位操作,子串通常稱(chēng)為模式串

int Index(SString S, SString T, int pos)
{
    int i=pos, j=1;
    while(i<=S.length&&j<=T.length){
        if(S.ch[i]==T.ch[j]){
            ++i; ++j;
        }
        else{
            i=i-j+2; j=1;
        }
    }
    if(j>T.length) return i-T.length;
    else return 0;
}

最壞時(shí)間復(fù)雜度O(nm)

改進(jìn)的模式匹配算法——KMP
利用比較過(guò)的信息,i指針不需要回溯,僅將子串向后滑動(dòng)一個(gè)合適的位置,并從這個(gè)位置開(kāi)始和主串進(jìn)行比較,這個(gè)合適的位置僅與子串本身的結(jié)構(gòu)有關(guān),而與主串無(wú)關(guān)。
前綴,后綴,部分匹配值

前綴后綴部分匹配值.PNG

KMP過(guò)程.PNG

用上圖中的next數(shù)組的話,匹配失敗時(shí)去找它前一個(gè)元素的部分匹配值,這樣有點(diǎn)不便,所以將next數(shù)組右移一位,第一位補(bǔ)-1,這樣哪個(gè)元素匹配失敗直接看它自己對(duì)應(yīng)的值即可。
Move=(j-1)-next[j]
j=j-Move=j-((j-1)-next[j])=next[j]+1
有時(shí)為了使公式更加簡(jiǎn)潔,將next數(shù)組整體加1,這樣j=next[j]

計(jì)算機(jī)求next數(shù)組的方法

void get_next(String T, int next[])
{
    int i=1, j=0;
    next[1]=0;
    while(i<T.length){
        if(j==0||T.ch[i]==T.ch[j]){
            ++i; ++j; next[i]=j;
        }
        else
            j=next[j];
    }
}
求next.PNG
int Index_KMP(String S, String T, int next[], int pos)
{
    int i=pos, j=1;
    while(i<=S.length&&j<=T.length){
        if(j==0||S.ch[i]==T.ch[j]){
            ++i;++j;
        }
        else
            j=next[j];
    }
    if(j>T.length)
        return i-T.length;
    else
        return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容