我們新設定了乙個nextval陣列,nextval[j]表示優化後的在j失配,它應該退回的位置。我們原來求解j回退位置k時,其實還是存在無用功。如果p[j]=p[k],而我們在j位置發生了失配,j回退到k的位置,結果它的字元和j一樣,那就無意義啊,因為它肯定還是會失配的,只有不一樣的時候,才有可能匹配成功。所以當p[j]=p[k]我們就需要繼續轉到k=next[k]的位置上,然後比較新的p[k]是否等於p[j]如果等於,我們就需要再繼續走,直到退到的字元不等於p[j],或者退到無路可退,也就是k為-1了。我們再仔細思考一下如果p[k]=p[j],我們是不是可以直接讓
nextval[j]=nextval[k],因為我們的思想是從低下標開始求對應nextval值,如果已經求到nextval[j]時,k位置對應的nextval值早就已經優化過了,它保證了如果在k發生失配,則它退回的位置要麼對應的字元是不同的,要麼就是-1,也就是無路可退了。如果p[j]和p[k]是不同的,那nextval[j]=k;
好,我們來看一下**實現:
tatic void getnext(const char*sub,int *next)
else
}}static void getnextval(const char*sub,int *next,int *nextval)
else
j++;}}
//kmp 演算法特點:i不回退,時間複雜度o(n+m)
int kmp(const char *str,const char *sub,int pos)//o(n+m)
int lenstr = strlen(str);
int lensub = strlen(sub);
int i = pos;
int j = 0;
int *next = (int *)malloc(lensub*sizeof(int));
getnext(sub,next);
int *nextval=(int*)malloc(lensub*sizeof(int));
getnextval(sub,next,nextval);
while(i
else//i不回退,j退到next[j](即k位置)
}free(next);
free(nextval);
if(j >= lensub)//找到了
else
}標紅的位置是相對於kmp演算法,它優化之後新增的**。
KMP演算法及其優化
今天來記錄一下,關於字元匹配的kmp演算法。給定字串text和pattern,需要判斷字串pattern是否為test的子串。pattern一般稱為模式串,text為文字串。若匹配成功,則讓函式返回,匹配開始處的下標,否則,返回 1。假設有乙個字串s,它以i號位作為結尾的子串就是s 1 i 對該字串...
經典演算法之KMP演算法及其優化
kmp演算法的具體分析見 author s email wardseptember gmail.com date 2017.12.18 kmp演算法 include include using namespace std define maxsize 50 void getnext char sub...
C 實現KMP演算法及其優化
自己寫了乙個簡潔版本,加注釋。第乙個函式是得到kmp的next陣列。1 設定next的第乙個值為 1。2 遍歷剩下的t串 3 t串前後比較,相等就在next中對應位置加1 4 不等,就回溯 t串中等價位置 void getnext string t,int next else j next j 第二...