字串匹配 sunday演算法

2021-07-05 16:47:57 字數 1758 閱讀 1053

原題:lintcode題目

字串查詢(又稱查詢子字串),是字串操作中乙個很有用的函式。你的任務是實現這個函式。

對於乙個給定的 source 字串和乙個 target 字串,你應該在 source 字串中找出 target 字串出現的第乙個位置(從0開始)。

如果不存在,則返回-1

字串匹配最常見的就是kmp演算法,不過kmp演算法對於我來說過於的複雜,我在網上查詢,發現了更為簡單,易於理解的sunday演算法

sunday演算法是daniel m.sunday於2023年提出的字串模式匹配

。其核心思想是:在匹配過程中,模式串發現不匹配時,演算法能跳過盡可能多的字元以進行下一步的匹配,從而提高了匹配效率。

unday是乙個字串

模式匹配演算法。演算法的概念如下:

sunday演算法是daniel m.sunday於2023年提出的一種字串

模式匹配演算法演算法。其核心思想是:在匹配過程中,模式串並不被要求一定要按從左向右進行比較還是從右向左進行比較,它在發現不匹配時,演算法能跳過盡可能多的

字元以進行下一步的匹配,從而提高了匹配效率。

假設在發生不匹配時s[i]≠t[j],1≤i≤n,1≤j≤m。此時已經匹配的部分為u,並假設字串u的長度為l。如圖1。明顯的,s[l+i+1]肯定要參加下一輪的匹配,並且t[m]至少要移動到這個位置(即模式串t至少向右移動乙個字元的位置)。

1 sunday

演算法不匹配的情況

分如下兩種情況:

(1) s[l+i+1]在模式串t中沒有出現。這個時候模式串t[0]移動到s[l+i+1]之後的字元的位置。如圖2。

2 sunday

演算法移動的第

1種情況

(2)s[l+i+1]在模式串中出現。這裡s[l+i+1]從模式串t的右側,即按t[m-1]、t[m-2]、…t[0]的次序查詢。如果發現s[l+i+1]和t中的某個字元相同,則記下這個位置,記為k,1≤k≤m,且t[k]=s[l+i+1]。此時,應該把模式串t向右移動m-k個字元的位置,即移動到t[k]和s[l+i+1]對齊的位置。如圖3。

3 sunday

演算法移動的第

2種情況

依次類推,如果完全匹配了,則匹配成功;否則,再進行下一輪的移動,直到

主串s的最右端結束。該演算法最壞情況下的

時間複雜度為o(n*m)。對於短模式串的匹配問題,該演算法執行速度較快。

sunday演算法思想跟bm演算法很相似,在匹配失敗時關注的是文字串中參加匹配的最末位字元的下一位字元。如果該字元沒有在匹配串中出現則直接跳過,即移動步長= 匹配串長度+1;否則,同bm演算法一樣其移動步長=匹配串中最右端的該字元到末尾的距離+1。

在這裡給出**.

int strstr(const char *source, const char *target) ;//next陣列儲存在target中出現字元順序,這樣在匹配的時候不需要重新查詢,
len_d=strlen(target);

for(j=0;j<256;++j) //初始化next陣列,如果next沒有在target中出現,next為target長度+1,即跳過整個target長度

next[j]=len_d + 1;

for(j=0;j//next的字元在target出現,者next值為target內的順序+1

while( pos

{i=pos;

for(j=0;j

字串匹配sunday演算法

在網上看到了一種比kmp和bm演算法還快字串匹配演算法,就看了一下,並且發現一些部落格上寫的 是錯誤的,於是我也寫了乙個,leetcode上測試通過。首先對sunday演算法進行一下講解 從別的地方複製過來的,講的確實不錯 好了,sunday演算法還真的很好理解,用下面的例子來說明吧 j k t h...

字串匹配 Sunday演算法

字串匹配演算法中最先學的演算法是暴力演算法,緊接著是kmp演算法,到現在依舊沒有理解next到底是怎麼求的 尋找到了一種新的演算法 sunday演算法,比kmp演算法更快 匹配時關注匹配主串中參與匹配的最後一位字元的下一位字元。參考 include includeusing namespace st...

字串匹配演算法 Sunday

以往不論是上課還是各種資料書上,看到關於字串匹配的演算法,大抵都是kmp了。然而kmp的next陣列理解起來頗為費勁,且容易忘記。在leetcode刷題中偶然發現了乙個叫sunday的演算法,不僅容易理解,且經過其他博主測評,sunday的效率還要高於kmp演算法,因此本文記錄一下sunday演算法...