給定兩個字串s1,s2,其長度分別為m和n,且m>n;判斷s1中是否存在s2,若存在則返回s2在s1中第乙個字元的索引位置,否則直接返回-1。
首先獲取子串的最長字首與最長字尾陣列每個陣列的數值分別與子串中每個字元相對應,表示該字元最長字首與最長字尾的大小,並且最長字首不能包括最後乙個字元,最長字尾不能包括第乙個字元;對於乙個字元而言,第乙個字元對應的數值為-1,第二個數值對應為0,整體從索引為2的位置開始進行計算。對當前字元而言,若其後乙個字元與後乙個字元對應的最長字首的下乙個字元相等,則當前字元最長字首與最長字尾數值等於前乙個字元的數值加1,否則若兩者不相等,在前乙個字元的最長字首不為0的情況下,跳到下乙個字元的位置然後與當前字元進行比較,若一直到最後都依然不匹配,則將當前字元的數值賦值為0;獲取上述子串的陣列之後,接下來便是依次對兩個字串對應數值進行比較,分別定義兩個指標m,n指向兩個字元陣列,當兩個指標指向的字元相等時,則將兩個指標前移一位,當兩個字元不相等時,若當前子串字元對應位置的最長字首與最長字尾數值為-1,則說明此時子串已經位於第乙個字元的位置,已經沒法再次移動,則將長串的字元位置前移一位,否則將子串移動到當前不等字元對應的最長字首的位置再次與之前不等的長串的字元進行比較。
public static int getindex(char chr)
; ///若當前字元陣列的長度小於1,則直接返回-1
} int index = new int[chr.length]; ///定義乙個與字元陣列長度相等的索引陣列
index[0] = -1;
index[1] = 0; ///前兩個字元索引為固定數值
int i = 2; 從第二個索引的位置開始進行計算
int cn= 0; ///這裡的cn表示的當前索引位置的最長字首字尾數的後乙個字元的位置
while(i0) ///到這裡說明兩個數值不相等,則將cn的數值向前推進,再次進行比較
else 若達到這裡說明此時cn也已經不能再向前推進,直接將當前字元索引的位置賦值為0
} return index; 返回子串的最長字首與最長字尾陣列
}
public static int kmpalgorithm(string s1,string s2)
char chr1 = s1.tochararray();
char chr2 = s2.tochararray();
int j1 = 0;
int j2 = 0;
int index = getindex(chr2);獲得子串的最長字首以及最長字尾陣列
while(j1else if(index[j2]==-1) ///如當前子串數值的最長字首以及最長字尾陣列的索引陣列已經為-1,說明此時子串陣列已經不能在往前移動,此時只能將長串向前
///移動乙個位置,這就說明,當前字元與子串的第乙個字元都不能進行匹配
else ///否則即將當前子串的索引位置移動到當前字元最長字首以及最長字尾的位置,然後繼續進行比較
}return j2==chr2.length ? j1 - j2:-1; 若當前子串的指標與其長度相等說明,此時已經在長串中找到符合要求的子串,
此時直接返回子串在長串中第乙個字元的索引位置,否則返回-1;
}
KMP演算法總結
kmp題目重在理解next陣列的含義 next陣列的作用 next j 記錄模式串中第 j 個字元的最長公共字首長度 重要,這是它的意義所在 第二種理解方式,當模式串與主串失配時,跳回的位置。next len 即字串 0 結束標誌的next值 單個字串匹配時與週期有關 hdu 1711 模板題 33...
KMP演算法總結
kmp演算法是用來實現模式匹配的,其時間複雜度是o m n 具體原理見 其中有用到next陣列來計算子串中公共項的位數,簡單來說,就是子串遇到不匹配時,就查next資料來決定前進幾位 移動位數 已匹配的字元數 對應的部分匹配值 1 要不要減一看next陣列第一位是不是為1,個人覺得加一後是有好處的,...
KMP演算法總結
現在假設有兩個字串a bbc abcdab abcdabde,b abcdabd。現在要在a中找b。比較暴力的方法是直接搜尋 void gosearch 上述 最核心就是while迴圈,舉兩個例子說明其作用 還是選取b串作為說明。假設現在要求next 6 那麼當前的j next 5 1 next陣列...