先不說演算法不演算法的的,怎麼知道乙個字串(模式串p)在是否在另乙個字串(字串t)中呢?序號1
2345
6789
10字串tab
cabo
kanp
模式串pab
cabd
正常的人就會想,我乙個乙個字元比對過去不久行了嗎,總結成思想就是
模式串p和字串t一位一位比,相同就往後比較,不同就移動一下模式串,繼續比先看第0位,t[1]是a,p[1]也是a,即t[1]=p[1],那就接著比後面的,
再看第1位,t[2]是b,p[2]也是b,即t[2]=p[2],那就接著比後面的,
…再看第5位,t[6]是o,p[6]是d,即t[6]不等於p[6],字串匹配失效了,那就挪一下模式串p的位置,接著繼續比較,總的來說就是下面這樣的,正常人應該都能想到序號1
2345
6789
10字串tab
cabo
kanp
模式串pab
cabd
模式串pab
cabd
模式串pab
cabd
但是這樣的方法效率非常的低,一次一次的滑動,然後進行比較,時間複雜度為o(m
n)
o(mn)
o(mn
)。那有沒有其他的方法,序號1
2345
6789
10字串tab
cabo
kanp
模式串pab
cabd
我們可以看到在第6位的時候才發現匹配不對了,這說明前5位是匹配的,我們往後移動一位再跟字串t匹配。其實不用看目標串t,只看模式串p,我們也能夠「預知」接下來的第2次和第3次比較是肯定會失敗的。為什麼呢,下面說明一下
已知
t[1]
=p[1]t[
2]=p[2]t[
3]=p[3]t[
4]=p[4]t[
5]=p[5]t[
6]!=p[
6]
移動一位比較
t[
2]與p[
1]比較t[3
]與p[
2]比較t[4
]與p[
3]比較t[5
]與p[
4]比較t[6
]與p[
5]比較
進行簡單的轉換,t[1:
5]= p[1:
5],也就是說p[2
]與p[
1]比較p[3
]與p[
2]比較p[4
]與p[
3]比較p[5
]與p[
4]比較p[6
]與p[
5]比較
目標串
t[1] =a
t[2]=b
t[3]=c
t[4]=a
t[5]=b
t[6]=o
模式串p
p[1]=a
p[2]=b
p[3]=c
p[4]=a
p[5]=b
p[6]=d
模式串p
p[1] =a
p[2]=b
p[3]=c
p[4]=a
p[5]=b
p[1]不等於p[2],所以咱們就知道移動一位後還是會匹配失敗的。
再移動一位比較呢
t[
3]與p[
1]比較t[4
]與p[
2]比較t[5
]與p[
3]比較t[6
]與p[
4]比較t[7
]與p[
5]比較
進行乙個簡單的轉換,t[1:
5]= p[1:
5],也就是說p[3
]與p[
1]比較p[4
]與p[
2]比較p[5
]與p[
3]比較p[6
]與p[
4]比較p[7
]與p[
5]比較
發現p[3] != p1[1]
進而可以直接推導出t[3] != p1[1]
,匹配會失敗序號1
2345
6789
10模式串pab
cabd
模式串pab
cabd
咱們想要把p直接多移動幾位,那該移動幾位呢,或者說該移動到**呢,再來手動試試找找感覺。
移動一位,p[1]!=p[2]->p[1]!=t[2],可以知道字串匹配不上序號1
2345
678模式串pab
cab模式串pab
cab移動兩位,p[1]!=p[3]->p[1]!=t[3],可以知道字串匹配不上序號1
2345
678模式串pab
cab模式串pab
cab移動三位,p[1]=p[4]->p[1]=t[4],字串匹配上了,而且p[2]=p[5]->p[2]=t[5],咱們直接比較p[3]跟t[6]就可以了。
目標串t序號12
3456
78模式串pab
cab模式串pab
cab可以很直觀的看到,如果字串字首和字串字尾相等,咱們就可以直接把字首對到字尾的位置,然後繼續比較後面的字元就可以了
目標串t序號12
ijnn+1
模式串p
p[1]
p[2]
…p[i]……
p[j]……
p[n]
模式串p和目標串t不匹配的字元位
模式串p
p[1]
p[2]
…p[i]
繼續比較t[n+1]和p[i+1]
為了不遺漏字元,這裡需要最長的公共前字尾,可以看一下大佬們的證明。可以看到,由原來的移動一位比較,現在可以直接移動j位了,並且,下一次比較可以直接從p[i+1]進行比較,因為1到i是匹配的。
字串匹配——sunday演算法
實現 strstr()
字串匹配之KMP演算法
以前零零散散做了些kmp的題目,一直也沒找出時間整理,這一段又開始研究字串了,就順便把kmp整理了一下。廢話不說了,我們直接入題。說到kmp,首先應該知道,它是一種字串查詢演算法,因為是由乙個姓k,乙個姓m和乙個姓p的人聯合發表的,所以就叫kmp演算法了。kmp演算法是一種線性時間的的字串匹配演算法...
演算法 字串匹配之KMP
說人話就是 比如有乙個字串 bbc abcdab abcdabcdabde 我想知道,裡面是否包含另乙個字串 abcdabd 許多演算法可以完成這個任務,kmp演算法是最常用的之一。首先對於上面的 比如 我們首先要針對搜尋詞 abcdabd 算出一張 部分匹配表 接下來就很簡單了,將字串和搜尋詞都從...
字串匹配之KMP演算法
問題定義 字串匹配即是在所有文字t中,找出模式p的所有出現。字串匹配常用的演算法有 樸素演算法 rabin karp演算法 有限自動機演算法 kmp演算法 所有演算法中,算kmp演算法效率最高。也較為難理解。作者曾經認真看了3遍嚴蔚敏的 資料結構 遺憾的是沒有看懂,搞得我一度懷疑自己的智商很低。今天...