成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

淺析Python實(shí)現(xiàn)DFA算法

瀏覽:201日期:2022-06-15 17:06:07
目錄一、概述二、匹配關(guān)鍵詞三、算法實(shí)現(xiàn)3.1、構(gòu)建存儲(chǔ)結(jié)構(gòu)3.2、匹配關(guān)鍵詞3.3、完整代碼四、其他用法4.1、添加通配符一、概述

計(jì)算機(jī)操作系統(tǒng)中的進(jìn)程狀態(tài)與切換可以作為 DFA 算法的一種近似理解。如下圖所示,其中橢圓表示狀態(tài),狀態(tài)之間的連線表示事件,進(jìn)程的狀態(tài)以及事件都是可確定的,且都可以窮舉。

淺析Python實(shí)現(xiàn)DFA算法

DFA 算法具有多種應(yīng)用,在此先介紹在匹配關(guān)鍵詞領(lǐng)域的應(yīng)用。

二、匹配關(guān)鍵詞

我們可以將每個(gè)文本片段作為狀態(tài),例如“匹配關(guān)鍵詞”可拆分為“匹”、“匹配”、“匹配關(guān)”、“匹配關(guān)鍵”和“匹配關(guān)鍵詞”五個(gè)文本片段。

淺析Python實(shí)現(xiàn)DFA算法

【過程】:

初始狀態(tài)為空,當(dāng)觸發(fā)事件“匹”時(shí)轉(zhuǎn)換到狀態(tài)“匹”; 觸發(fā)事件“配”,轉(zhuǎn)換到狀態(tài)“匹配”; 依次類推,直到轉(zhuǎn)換為最后一個(gè)狀態(tài)“匹配關(guān)鍵詞”。

再讓我們考慮多個(gè)關(guān)鍵詞的情況,例如“匹配算法”、“匹配關(guān)鍵詞”以及“信息抽取”。

淺析Python實(shí)現(xiàn)DFA算法

可以看到上圖的狀態(tài)圖類似樹形結(jié)構(gòu),也正是因?yàn)檫@個(gè)結(jié)構(gòu),使得 DFA 算法在關(guān)鍵詞匹配方面要快于關(guān)鍵詞迭代方法(for 循環(huán))。經(jīng)常刷 LeetCode 的讀者應(yīng)該清楚樹形結(jié)構(gòu)的時(shí)間復(fù)雜度要小于 for 循環(huán)的時(shí)間復(fù)雜度。

for 循環(huán):

keyword_list = []for keyword in ['匹配算法', '匹配關(guān)鍵詞', '信息抽取']: if keyword in 'DFA 算法匹配關(guān)鍵詞':keyword_list.append(keyword)

for 循環(huán)需要遍歷一遍關(guān)鍵詞表,隨著關(guān)鍵詞表的擴(kuò)充,所需的時(shí)間也會(huì)越來越長。

DFA 算法:找到“匹”時(shí),只會(huì)按照事件走向特定的序列,例如“匹配關(guān)鍵詞”,而不會(huì)走向“匹配算法”,因此遍歷的次數(shù)要小于 for 循環(huán)。具體的實(shí)現(xiàn)放在下文中。

【問】:那么如何構(gòu)建狀態(tài)圖所示的結(jié)構(gòu)呢?

【答】:在 Python 中我們可以使用 dict 數(shù)據(jù)結(jié)構(gòu)。

state_event_dict = { '匹': {'配': { '算': {'法': { 'is_end': True},'is_end': False }, '關(guān)': {'鍵': { '詞': {'is_end': True }, 'is_end': False},'is_end': False }, 'is_end': False},'is_end': False }, '信': {'息': { '抽': {'取': { 'is_end': True},'is_end': False }, 'is_end': False},'is_end': False }}

用嵌套字典來作為樹形結(jié)構(gòu),key 作為事件,通過 is_end 字段來判斷狀態(tài)是否為最后一個(gè)狀態(tài),如果是最后一個(gè)狀態(tài),則停止?fàn)顟B(tài)轉(zhuǎn)換,獲取匹配的關(guān)鍵詞。

【問】:如果關(guān)鍵詞存在包含關(guān)系,例如“匹配關(guān)鍵詞”和“匹配”,那么該如何處理呢?

【答】:我們?nèi)匀豢梢杂?is_end 字段來表示關(guān)鍵詞的結(jié)尾,同時(shí)添加一個(gè)新的字段,例如 is_continue 來表明仍可繼續(xù)進(jìn)行匹配。除此之外,也可以通過尋找除 is_end 字段外是否還有其他的字段來判斷是否繼續(xù)進(jìn)行匹配。例如下面代碼中的“配”,除了 is_end 字段外還有“關(guān)”,因此還需要繼續(xù)進(jìn)行匹配。

state_event_dict = { '匹': {'配': { '關(guān)': {'鍵': { '詞': {'is_end': True }, 'is_end': False},'is_end': False }, 'is_end': True},'is_end': False }}

接下來,我們來實(shí)現(xiàn)這個(gè)算法。

三、算法實(shí)現(xiàn)

使用 Python 3.6 版本實(shí)現(xiàn),當(dāng)然 Python 3.X 都能運(yùn)行。

3.1、構(gòu)建存儲(chǔ)結(jié)構(gòu)

def _generate_state_event_dict(keyword_list: list) -> dict: state_event_dict = {} # 遍歷每一個(gè)關(guān)鍵詞 for keyword in keyword_list:current_dict = state_event_dictlength = len(keyword)for index, char in enumerate(keyword): if char not in current_dict:next_dict = {'is_end': False}current_dict[char] = next_dictcurrent_dict = next_dict else:next_dict = current_dict[char]current_dict = next_dict if index == length - 1:current_dict['is_end'] = True return state_event_dict

關(guān)于上述代碼仍然有不少可迭代優(yōu)化的地方,例如先對(duì)關(guān)鍵詞列表按照字典序進(jìn)行排序,這樣可以讓具有相同前綴的關(guān)鍵詞集中在一塊,從而在構(gòu)建存儲(chǔ)結(jié)構(gòu)時(shí)能夠減少遍歷的次數(shù)。

3.2、匹配關(guān)鍵詞

def match(state_event_dict: dict, content: str): match_list = [] state_list = [] temp_match_list = [] for char_pos, char in enumerate(content):# 首先找到匹配項(xiàng)的起點(diǎn)if char in state_event_dict: state_list.append(state_event_dict) temp_match_list.append({'start': char_pos,'match': '' })# 可能會(huì)同時(shí)滿足多個(gè)匹配項(xiàng),因此遍歷這些匹配項(xiàng)for index, state in enumerate(state_list): if char in state:state_list[index] = state[char]temp_match_list[index]['match'] += char# 如果抵達(dá)匹配項(xiàng)的結(jié)尾,表明匹配關(guān)鍵詞完成if state[char]['is_end']: match_list.append(copy.deepcopy(temp_match_list[index])) # 如果還能繼續(xù),則繼續(xù)進(jìn)行匹配 if len(state[char].keys()) == 1:state_list.pop(index)temp_match_list.pop(index) # 如果不滿足匹配項(xiàng)的要求,則將其移除 else:state_list.pop(index)temp_match_list.pop(index) return match_list3.3、完整代碼

import reimport copyclass DFA: def __init__(self, keyword_list: list):self.state_event_dict = self._generate_state_event_dict(keyword_list) def match(self, content: str):match_list = []state_list = []temp_match_list = []for char_pos, char in enumerate(content): if char in self.state_event_dict:state_list.append(self.state_event_dict)temp_match_list.append({ 'start': char_pos, 'match': ''}) for index, state in enumerate(state_list):if char in state: state_list[index] = state[char] temp_match_list[index]['match'] += char if state[char]['is_end']:match_list.append(copy.deepcopy(temp_match_list[index]))if len(state[char].keys()) == 1: state_list.pop(index) temp_match_list.pop(index)else: state_list.pop(index) temp_match_list.pop(index)return match_list @staticmethod def _generate_state_event_dict(keyword_list: list) -> dict:state_event_dict = {}for keyword in keyword_list: current_dict = state_event_dict length = len(keyword) for index, char in enumerate(keyword):if char not in current_dict: next_dict = {'is_end': False} current_dict[char] = next_dict current_dict = next_dictelse: next_dict = current_dict[char] current_dict = next_dictif index == length - 1: current_dict['is_end'] = Truereturn state_event_dictif __name__ == '__main__': dfa = DFA(['匹配關(guān)鍵詞', '匹配算法', '信息抽取', '匹配']) print(dfa.match('信息抽取之 DFA 算法匹配關(guān)鍵詞,匹配算法'))

輸出:

[

    {

        ’start’: 0, 

        ’match’: ’信息抽取’

    }, {

        ’start’: 12, 

        ’match’: ’匹配’

    }, {

        ’start’: 12, 

        ’match’: ’匹配關(guān)鍵詞’

    }, {

        ’start’: 18, 

        ’match’: ’匹配’

    }, {

        ’start’: 18,

        ’match’: ’匹配算法’

    }

]

四、其他用法4.1、添加通配符

在敏感詞識(shí)別時(shí)往往會(huì)遇到同一種類型的句式,例如“你這個(gè)傻X”,其中 X 可以有很多,難道我們需要一個(gè)個(gè)添加到關(guān)鍵詞表中嗎?最好能夠通過類似正則表達(dá)式的方法去進(jìn)行識(shí)別。一個(gè)簡單的做法就是“*”,匹配任何內(nèi)容。

添加通配符只需要對(duì)匹配關(guān)鍵詞過程進(jìn)行修改:

def match(self, content: str): match_list = [] state_list = [] temp_match_list = [] for char_pos, char in enumerate(content):if char in self.state_event_dict: state_list.append(self.state_event_dict) temp_match_list.append({'start': char_pos,'match': '' })for index, state in enumerate(state_list): is_find = False state_char = None # 如果是 * 則匹配所有內(nèi)容 if '*' in state:state_list[index] = state['*']state_char = state['*']is_find = True if char in state:state_list[index] = state[char]state_char = state[char]is_find = True if is_find:temp_match_list[index]['match'] += charif state_char['is_end']: match_list.append(copy.deepcopy(temp_match_list[index])) if len(state_char.keys()) == 1:state_list.pop(index)temp_match_list.pop(index) else:state_list.pop(index)temp_match_list.pop(index) return match_list

main() 函數(shù)。

if __name__ == '__main__': dfa = DFA(['匹配關(guān)鍵詞', '匹配算法', '信息*取', '匹配']) print(dfa.match('信息抽取之 DFA 算法匹配關(guān)鍵詞,匹配算法,信息抓取'))

輸出:

[

    {

        ’start’: 0, 

        ’match’: ’信息抽取’

    }, {

        ’start’: 12,

        ’match’: ’匹配’

    }, {

        ’start’: 12,

        ’match’: ’匹配關(guān)鍵詞’

    }, {

        ’start’: 18,

        ’match’: ’匹配’

    }, {

        ’start’: 18,

        ’match’: ’匹配算法’

    }, {

        ’start’: 23,

        ’match’: ’信息抓取’

    }

]

以上就是淺析Python實(shí)現(xiàn)DFA算法的詳細(xì)內(nèi)容,更多關(guān)于Python DFA算法的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Python 編程
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
在线影视一区二区三区| 久久精品视频在线看| 国产欧美1区2区3区| 欧美成人艳星乳罩| 欧美精品成人一区二区在线观看| 国产女主播视频一区二区| 欧美三级视频在线观看| 99热精品在线观看| 成av人片一区二区| 蜜臀av性久久久久蜜臀aⅴ | 国产精品porn| 成人午夜电影小说| 精品在线观看视频| 天天av天天翘天天综合网色鬼国产| 欧美性一二三区| aaa国产一区| 久久99蜜桃精品| 五月婷婷激情综合网| 一区二区三区在线高清| 一区二区中文字幕在线| 亚洲欧美在线观看| 中文字幕在线观看一区| 久久久影视传媒| 国产精品视频看| 国产精品久久久久久久午夜片 | 综合网在线视频| 国产精品护士白丝一区av| 中文字幕欧美日韩一区| 欧美激情一区二区三区四区| 久久女同互慰一区二区三区| 欧美草草影院在线视频| ww久久中文字幕| 久久亚洲精品小早川怜子| 久久久久久**毛片大全| 国产欧美综合色| 亚洲少妇30p| 亚洲国产成人av网| 精品一区二区三区影院在线午夜| 精品一区二区三区在线观看国产 | 亚洲茄子视频| 不卡视频免费播放| 波多野结衣在线一区| 亚洲最大成人网4388xx| 26uuu亚洲综合色| 国产精品日韩欧美一区二区| 91在线视频免费91| 久久国产精品区| 国产精品影视在线观看| 久久久久久婷| 亚洲视频免费在线观看| 激情国产一区二区| 亚洲一区二区三区色| 国产成人综合在线播放| 韩国免费一区| 色噜噜狠狠一区二区三区果冻| 玖玖在线精品| 久久不射2019中文字幕| 日韩女优av电影| 欧美国产日韩在线观看| 亚洲女性喷水在线观看一区| 91.com在线观看| 日韩无一区二区| 中文字幕在线播放不卡一区| 欧美日韩一区精品| 精品国产自在久精品国产| 日韩制服丝袜先锋影音| 夜夜操天天操亚洲| 国产精品a级| 日韩午夜视频在线观看| 精品国一区二区三区| www.成人在线| 亚洲精品视频在线| 亚洲综合好骚| 国产黑丝在线一区二区三区| 欧美午夜一区二区福利视频| 国产欧美视频一区二区三区| 欧美午夜免费| 天天亚洲美女在线视频| 欧美日韩国产经典色站一区二区三区 | 国产伦精品一区二区三区四区免费| 欧美精品少妇一区二区三区| 国产一区二区在线观看视频| 黄色在线成人| 欧美精品一级二级| 中文字幕av一区二区三区免费看 | 亚洲欧美日韩精品久久久久| 国产精品一区二区三区乱码| 欧美剧情电影在线观看完整版免费励志电影 | 欧美影院一区二区| 精品一区精品二区高清| 欧美日韩国产成人在线91| 欧美96一区二区免费视频| 一本久久a久久免费精品不卡| 亚洲成人免费影院| 欧美性欧美巨大黑白大战| 国产成人av福利| 久久综合视频网| 在线精品一区| 久久国产剧场电影| 久久人人97超碰com| 国产精品一区二区三区四区五区 | 国产日韩综合| 中文字幕av一区二区三区免费看 | 亚洲在线播放| 1000精品久久久久久久久| 91亚洲国产成人精品一区二区三| 欧美日韩精品系列| 99久久久久久| 五月天中文字幕一区二区| 91精品国产综合久久香蕉麻豆| 亚洲永久精品国产| 欧美日韩大陆在线| 欧美激情日韩| 经典三级一区二区| 亚洲欧洲国产日韩| 91精品国产高清一区二区三区| 色综合久久综合网欧美综合网 | 在线播放亚洲一区| 伊人久久成人| 99国内精品久久| 日韩高清在线一区| 国产精品白丝在线| www国产精品av| 亚洲精品偷拍| 成人性生交大合| 国产美女一区二区| 日本中文字幕一区二区有限公司| 国产欧美一区二区三区网站| 欧美在线视频日韩| 亚洲精品三级| 国产综合久久| 欧美喷水视频| 亚洲一二三区精品| 欧美午夜视频| 99精品福利视频| 亚洲成色最大综合在线| 欧美午夜不卡| 99国产精品久久久久久久| 黄色av成人| 最新日韩av| 国产精品欧美日韩一区| 性xx色xx综合久久久xx| 美日韩免费视频| 在线国产电影不卡| 欧美日韩视频一区二区| 日韩一区二区精品在线观看| 欧美一级视频精品观看| 精品国产一区二区三区av性色 | 欧美电影一区二区| 精品三级av在线| 国产精品妹子av| 婷婷国产v国产偷v亚洲高清| 免费高清视频精品| 欧美xxx在线观看| 国产区日韩欧美| 91精品国产日韩91久久久久久| 久久久蜜桃精品| 五月婷婷久久综合| jizzjizzjizz欧美| 一本一本久久| 久久精品日韩一区二区三区| 日韩视频在线观看一区二区| 日韩高清不卡一区二区| 亚洲免费av在线| 青青草国产精品97视觉盛宴| 91免费版在线| 欧美视频一区二区在线观看| 亚洲天堂成人网| 欧美凹凸一区二区三区视频| 亚洲资源av| 欧美日韩另类国产亚洲欧美一级| 亚洲女人****多毛耸耸8| 欧美午夜电影在线观看| 久久三级视频| 欧美不卡三区| 日韩成人免费在线| 国产精品美女视频| 欧美日本在线观看| 亚洲bt欧美bt精品777| 99re热这里只有精品免费视频| av在线不卡网| 99精品99久久久久久宅男| 91一区一区三区| 国产欧美日韩中文久久| 国产亚洲午夜| 欧美一个色资源| 一区精品在线播放| 欧美中文字幕一区二区三区| 91啪亚洲精品| 国产日韩亚洲欧美综合| 91女厕偷拍女厕偷拍高清| 国产美女精品人人做人人爽| 亚洲午夜精品网| 亚洲欧洲成人精品av97| 国产视频不卡一区| 99麻豆久久久国产精品免费| 男女精品网站| 亚洲一区日韩在线| 精品91自产拍在线观看一区| 亚洲.国产.中文慕字在线|