日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python实现Trie 树+朴素匹配字符串+RK算法匹配字符串+kmp算法匹配字符串

發布時間:2024/7/23 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python实现Trie 树+朴素匹配字符串+RK算法匹配字符串+kmp算法匹配字符串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.trie樹應用:

相應leetcode

常用于搜索提示,如當輸入一個網址,可以自動搜索出可能的選擇。當沒有完全匹配的搜索結果,可以返回前綴最相似的可能。

例如三個單詞app, apple, add,我們按照以下規則創建了一顆Trie樹.對于從樹的根結點走到黑色結點的路徑上的字母依次組合起來就是一個完整的單詞.?

class Trie:def __init__(self):"""Initialize your data structure here."""self.root = {}self.word_end = -1def insert(self, word):"""Inserts a word into the trie."""curNode = self.rootfor c in word:# print('==self.root:', self.root)if c not in curNode:curNode[c] = {}curNode = curNode[c]curNode[self.word_end] = Truedef search(self, word):"""Returns if the word is in the trie."""curNode = self.rootfor c in word:if c not in curNode:return FalsecurNode = curNode[c]# Doesn't end hereif self.word_end not in curNode:return Falsereturn Truedef startsWith(self, prefix):"""Returns if there is any word in the trie that starts with the given prefix."""curNode = self.rootfor c in prefix:if c not in curNode:return FalsecurNode = curNode[c]return Trueword = 'apple' prefix = 'ad' obj = Trie() obj.insert(word='apple') obj.insert(word='add') obj.insert(word='app') print('tree:', obj.root) param_2 = obj.search(word) print('search res:',param_2) param_3 = obj.startsWith(prefix) print('prefix find:',param_3)

二.字符串匹配算法

1.樸素匹配算法

暴力解法,時間復雜度是O(m*n)?。

t = 'aabaabaabab' p = 'abc' print(nmatching(t,p)) def match_string(t,p):n=len(t)m=len(p)i=j=0while i<n and j<m:if t[i]==p[j]:i+=1j+=1else:i=i-j+1j=0if j==m:return str(i-j)else:return 'no mismatch' res=match_string(t,p) print('res:',res)

2.RK算法

采用字符串的hash值進行匹配,時復雜度O(n),最差情況退化到樸素匹配,時間復雜度也為O(m*n)

def compute_hash(str_):"""a的hash值是0,其它依次加1"""hash_code = 0for i in range(len(str_)):# print('str_[i]', str_[i])hash_code += ord(str_[i])-ord('a')return hash_code#RK算法 def RK(main_str,pattern_str):"""通過比較字符串的hash值 從而找到子串 時間復雜度O(n),遇見復雜情況就退化為了O(mn))"""pattern_hash_code = compute_hash(pattern_str)pattern_len = len(pattern_str)print('==模式串hash_code', pattern_hash_code)str_hash_code = compute_hash(main_str[:pattern_len])print('==子串_hash_code', str_hash_code)for i in range(len(main_str)-len(pattern_str)+1):if str_hash_code == pattern_hash_code and main_str[i:i+len(pattern_str)] == pattern_str:return ielse:str_hash_code -= ord(main_str[i]) - ord('a')str_hash_code += ord(main_str[i + len(pattern_str)]) - ord('a') # hash_code = compute_hash('ab') # print('hash_code:', hash_code) # main_str = 'ad' # pattern_str = 'ad' main_str = 'aacdesadsdfer' pattern_str = 'adsd' index = RK(main_str, pattern_str) print('子串的位置在:', index)

3.KMP算法

記錄最長公共前后綴,然后字符串匹配按照這個來,時間復雜度O(n)

最長公共前后綴計算:

示意:

代碼:

#最長公共前后綴 def pefix_table(pattern):"""字符串最長公共前后綴思路:通過遍歷字符串來尋找公共部分,當出現不一樣的時候 需要回退直到比較首字符"""""" 'ababcabaa' """# """ 'ababa' """# 'aa'i = 0prefix = [0]*len(pattern)for j in range(1, len(pattern)):while(pattern[j]!=pattern[i] and i>0):#循環判斷如果發現沒有相等就一直回退直到i==0也就是首字符i = prefix[i-1]if pattern[j] == pattern[i]:#相等的話就記錄相等的長度i += 1prefix[j] = ielse:prefix[j] = 0#不相等的話就長度長公共前后綴記錄為0return prefixdef move_prefix(prefix):""""""real_prefix = [-1]*len(prefix)for i in range(len(prefix)-1):real_prefix[i+1]=prefix[i]return real_prefixstr_ = 'ababcabaa' # str_ = 'ababa' prefix = pefix_table(str_) print('==prefix:', prefix)

?

kmp匹配開始:

按照b的下標移動,會發現前面相似的不需要比對:

#最長公共前后綴 def pefix_table(pattern):"""字符串最長公共前后綴思路:通過遍歷字符串來尋找公共部分,當出現不一樣的時候 需要回退直到比較首字符"""""" 'ababcabaa' """# """ 'ababa' """# 'aa'i = 0prefix = [0]*len(pattern)for j in range(1, len(pattern)):while(pattern[j]!=pattern[i] and i>0):#循環判斷如果發現沒有相等就一直回退直到i==0也就是首字符i = prefix[i-1]if pattern[j] == pattern[i]:#相等的話就記錄相等的長度i += 1prefix[j] = ielse:prefix[j] = 0#不相等的話就長度長公共前后綴記錄為0return prefixdef move_prefix(prefix):""""""real_prefix = [-1]*len(prefix)for i in range(len(prefix)-1):real_prefix[i+1]=prefix[i]return real_prefix# str_ = 'ababcabaa' # # str_ = 'ababa' # prefix = pefix_table(str_) # print('==prefix:', prefix) # prefix = move_prefix(prefix) # print('==prefix:', prefix)def kmp(main_str,pattern_str):"""kmp比對"""i = 0j = 0n = len(pattern_str)while i < len(main_str):if j == n-1 and main_str[i] == pattern_str[j]:print('find pattern at {}'.format(i-j))j = prefix[j]if main_str[i] == pattern_str[j]:i += 1j += 1else:j = prefix[j]if j == -1:#找到邊界都向右移動一位i += 1j += 1pattern_str ='ababcabaa' main_str = 'abababcabaabababab'prefix = pefix_table(pattern_str) # print('==prefix:', prefix) prefix = move_prefix(prefix) print('==prefix:', prefix) kmp(main_str, pattern_str)

參考:

https://blog.csdn.net/weixin_42698229/article/details/90321230

https://blog.csdn.net/weixin_39561100/article/details/80822208

https://www.bilibili.com/video/BV1hW411a7ys/?spm_id_from=trigger_reload

總結

以上是生活随笔為你收集整理的python实现Trie 树+朴素匹配字符串+RK算法匹配字符串+kmp算法匹配字符串的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。