bf演算法,即暴力(brute force)演算法,是普通的模式匹配演算法,bf演算法的思想就是將目標串s的第乙個字元與模式串t的第乙個字元進行匹配,若相等,則繼續比較s的第二個字元和 t的第二個字元;若不相等,則比較s的第二個字元和t的第乙個字元,依次比較下去,直到得出最後的匹配結果。bf演算法是一種蠻力演算法。
def*****_matching(t, p):
m, n =len(p), len(t)
i, j =0, 0
while i < m and j < n: #
i==m means a matching
if p[i] == t[j]: #
ok! consider next char in p
i, j = i + 1, j + 1
else: #
no! consider next position in t
i, j = 0, j - i + 1
if i == m: #
find a matching, return its index
return j -i
return -1 #
no matching, return special value
t = "
aabababababbbbaababaaaababababbab
"p = "
abbab
"print(*****_matching(t, p))
kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt提出的,因此人們稱它為克努特—莫里斯—普拉特操作(簡稱kmp演算法)。kmp演算法的核心是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是通過乙個next()函式實現,函式本身包含了模式串的區域性匹配資訊。kmp演算法的時間複雜度o(m+n)。kmp演算法是各大教科書上的看家絕學,曾被投票選為當今世界最偉大的十大演算法之一;但是晦澀難懂,並且十分難以實現。
defkmp_matching(t, p):
"""kmp字串匹配的另乙個版本, 稍許修改(非本質).
將gen_pnext定義為區域性函式.
"""def gen_pnext(p): #
p = "abbab"
"""生成p中各i的下一檢查位置表,稍許優化版本.
"""i, k, m = 0, -1, len(p)
pnext = [-1] * m #
初始化乙個陣列
while i < m - 1: #
generate pnext[i+1]
if k == -1 or p[i] ==p[k]:
i, k = i + 1, k + 1
if p[i] ==p[k]:
pnext[i] =pnext[k]
else
: pnext[i] =k
else
: k =pnext[k]
return
pnext
j, i =0, 0
n, m =len(t), len(p)
pnext =gen_pnext(p)
while j < n and i < m: #
i==m means a matching
while i >= 0 and t[j] !=p[i]:
i =pnext[i]
j, i = j + 1, i + 1
if i == m: #
找到匹配, 返回其下標
return j -i
return -1 #
不存在匹配, 返回特殊值
t = "
aabababababbbbaababaaaababababbab
"p = "
abbab
"print(kmp_matching(t, p))
defgetbmbc(pattern):
#預生成壞字元表
bmbc =dict()
for i in range(len(pattern) - 1):
char =pattern[i]
#記錄壞字元最右位置(不包括模式串最右側字元)
bmbc[char] = i + 1
return
bmbc
defgetbmgs(pattern):
#預生成好字尾表
bmgs =dict()
#無字尾僅根據壞字移位符規則
bmgs[''] =0
for i in
range(len(pattern)):
#好字尾
gs = pattern[len(pattern) - i - 1:]
for j in range(len(pattern) - i - 1):
#匹配部分
ngs = pattern[j:j + i + 1]
#記錄模式串中好字尾最靠右位置(除結尾處)
if gs ==ngs:
bmgs[gs] = len(pattern) - j - i - 1
return
bmgs
defbm(string, pattern):
"""boyer-moore演算法實現字串查詢
"""m =len(pattern)
n =len(string)
i =0
j =m
indies =
bmbc = getbmbc(pattern=pattern) #
壞字元表
bmgs = getbmgs(pattern=pattern) #
好字尾表
while i while (j >0):
if i + j - 1 >= n: #
當無法繼續向下搜尋就返回值
return
indies
#主串判斷匹配部分
a = string[i + j - 1:i +m]
#模式串判斷匹配部分
b = pattern[j - 1:]
#當前位匹配成功則繼續匹配
if a ==b:
j = j - 1
#當前位匹配失敗根據規則移位
else
: i = i + max(bmgs.setdefault(b[1:], m), j - bmbc.setdefault(string[i + j - 1], 0))
j =m
#匹配成功返回匹配位置
if j ==0:
i += 1j =len(pattern)
t = "
aabababababbbbaababaaaababababbab
"p = "
abbab
"print(bm(t, p))
sunday演算法是daniel m.sunday於2023年提出的字串模式匹配。其核心思想是:在匹配過程中,模式串發現不匹配時,演算法能跳過盡可能多的字元以進行下一步的匹配,從而提高了匹配效率。目前發現的最高效且容易理解的演算法。
defsunday_match_str(main_str, find_str):
""":param main_str: 主串
:param find_str: 模式串
:return: 返回第乙個匹配到模式串中第乙個字元在主串中的下標
"""m, f =0, 0
m_len, f_len =len(main_str), len(find_str)
while m if main_str[m] ==find_str[f]:
m, f = m + 1, f + 1
if f ==f_len:
return m - f_len #
此時找到了第乙個匹配到的下標
continue
else
: flag = m - f +f_len
if flag > m_len - 1: #
main_str下標越界,沒有找到匹配的串
return -1check_exits =find_str.rfind(main_str[flag])
if check_exits != -1: #
在find_str中有匹配
jump = f_len - check_exits #
移動的步長
m, f = m - f +jump, 0
else: #
在find_str中無匹配
jump = f_len + 1 #
移動的步長
m, f = m - f +jump, 0
else
:
return -1t = "
aabababababbbbaababaaaababababbab
"p = "
abbab
"print(sunday_match_str(t, p))
常見的四種排序演算法
void bubblesort int a,int size,int order order為1代表公升序,氣泡排序演算法 void selectsort int a,int size,int order order為1代表公升序,選擇排序演算法 if k i void insertsort int...
四種PHP定義字串的方式
閱讀目錄 1 簡介 在php中這門語言中,因為是弱型別語言,因此使用變數時不需提前定義即可使用。我們在使用php進行開發的時候,大多數使用雙引號 單引號進行定義字串。既然有這兩種方式,那麼他們之間肯定是有區別的。並且,除了單雙引號定義字串這兩種方式外,php還增加了heredoc和nowdoc這兩種...
PHP定義字串的四種方式
1 單引號 在單引號中,任何特殊字元都會按原樣輸出 除 和 將會被轉義輸出 僅僅只有單引號 反斜槓被轉義 2 雙引號 在雙引號中,遇到 將會解析該變數 雙引號中會轉義反斜槓的轉義字元 單雙引號之間的區別 雙引號會替換變數的值,而單引號會把它當做字串輸出。對於轉義的支援 效能速度問題,由於雙引號中的字...