电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

淺析Python實現DFA算法

瀏覽:96日期:2022-06-15 17:06:07
目錄一、概述二、匹配關鍵詞三、算法實現3.1、構建存儲結構3.2、匹配關鍵詞3.3、完整代碼四、其他用法4.1、添加通配符一、概述

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

淺析Python實現DFA算法

DFA 算法具有多種應用,在此先介紹在匹配關鍵詞領域的應用。

二、匹配關鍵詞

我們可以將每個文本片段作為狀態,例如“匹配關鍵詞”可拆分為“匹”、“匹配”、“匹配關”、“匹配關鍵”和“匹配關鍵詞”五個文本片段。

淺析Python實現DFA算法

【過程】:

初始狀態為空,當觸發事件“匹”時轉換到狀態“匹”; 觸發事件“配”,轉換到狀態“匹配”; 依次類推,直到轉換為最后一個狀態“匹配關鍵詞”。

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

淺析Python實現DFA算法

可以看到上圖的狀態圖類似樹形結構,也正是因為這個結構,使得 DFA 算法在關鍵詞匹配方面要快于關鍵詞迭代方法(for 循環)。經常刷 LeetCode 的讀者應該清楚樹形結構的時間復雜度要小于 for 循環的時間復雜度。

for 循環:

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

for 循環需要遍歷一遍關鍵詞表,隨著關鍵詞表的擴充,所需的時間也會越來越長。

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

【問】:那么如何構建狀態圖所示的結構呢?

【答】:在 Python 中我們可以使用 dict 數據結構。

state_event_dict = { '匹': {'配': { '算': {'法': { 'is_end': True},'is_end': False }, '關': {'鍵': { '詞': {'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 }}

用嵌套字典來作為樹形結構,key 作為事件,通過 is_end 字段來判斷狀態是否為最后一個狀態,如果是最后一個狀態,則停止狀態轉換,獲取匹配的關鍵詞。

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

【答】:我們仍然可以用 is_end 字段來表示關鍵詞的結尾,同時添加一個新的字段,例如 is_continue 來表明仍可繼續進行匹配。除此之外,也可以通過尋找除 is_end 字段外是否還有其他的字段來判斷是否繼續進行匹配。例如下面代碼中的“配”,除了 is_end 字段外還有“關”,因此還需要繼續進行匹配。

state_event_dict = { '匹': {'配': { '關': {'鍵': { '詞': {'is_end': True }, 'is_end': False},'is_end': False }, 'is_end': True},'is_end': False }}

接下來,我們來實現這個算法。

三、算法實現

使用 Python 3.6 版本實現,當然 Python 3.X 都能運行。

3.1、構建存儲結構

def _generate_state_event_dict(keyword_list: list) -> dict: state_event_dict = {} # 遍歷每一個關鍵詞 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

關于上述代碼仍然有不少可迭代優化的地方,例如先對關鍵詞列表按照字典序進行排序,這樣可以讓具有相同前綴的關鍵詞集中在一塊,從而在構建存儲結構時能夠減少遍歷的次數。

3.2、匹配關鍵詞

def match(state_event_dict: dict, content: str): match_list = [] state_list = [] temp_match_list = [] for char_pos, char in enumerate(content):# 首先找到匹配項的起點if char in state_event_dict: state_list.append(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_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(['匹配關鍵詞', '匹配算法', '信息抽取', '匹配']) print(dfa.match('信息抽取之 DFA 算法匹配關鍵詞,匹配算法'))

輸出:

[

    {

        ’start’: 0, 

        ’match’: ’信息抽取’

    }, {

        ’start’: 12, 

        ’match’: ’匹配’

    }, {

        ’start’: 12, 

        ’match’: ’匹配關鍵詞’

    }, {

        ’start’: 18, 

        ’match’: ’匹配’

    }, {

        ’start’: 18,

        ’match’: ’匹配算法’

    }

]

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

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

添加通配符只需要對匹配關鍵詞過程進行修改:

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 # 如果是 * 則匹配所有內容 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() 函數。

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

輸出:

[

    {

        ’start’: 0, 

        ’match’: ’信息抽取’

    }, {

        ’start’: 12,

        ’match’: ’匹配’

    }, {

        ’start’: 12,

        ’match’: ’匹配關鍵詞’

    }, {

        ’start’: 18,

        ’match’: ’匹配’

    }, {

        ’start’: 18,

        ’match’: ’匹配算法’

    }, {

        ’start’: 23,

        ’match’: ’信息抓取’

    }

]

以上就是淺析Python實現DFA算法的詳細內容,更多關于Python DFA算法的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 除甲醛公司-甲醛检测治理-杭州创绿家环保科技有限公司-室内空气净化十大品牌 | 刮板输送机,粉尘加湿搅拌机,螺旋输送机,布袋除尘器 | 模具钢_高速钢_不锈钢-万利钢金属材料 | 专业生物有机肥造粒机,粉状有机肥生产线,槽式翻堆机厂家-郑州华之强重工科技有限公司 | 工业车间焊接-整体|集中除尘设备-激光|等离子切割机配套除尘-粉尘烟尘净化治理厂家-山东美蓝环保科技有限公司 | 踏板力计,制动仪,非接触多功能速度仪,逆反射系数测试仪-创宇 | 金环宇|金环宇电线|金环宇电缆|金环宇电线电缆|深圳市金环宇电线电缆有限公司|金环宇电缆集团 | 老城街小面官网_正宗重庆小面加盟技术培训_特色面馆加盟|牛肉拉面|招商加盟代理费用多少钱 | 锤式粉碎机,医药粉碎机,锥式粉碎机-无锡市迪麦森机械制造有限公司 | 【官网】博莱特空压机,永磁变频空压机,螺杆空压机-欧能优 | 耐高温风管_耐高温软管_食品级软管_吸尘管_钢丝软管_卫生级软管_塑料波纹管-东莞市鑫翔宇软管有限公司 | 光栅尺厂家_数显表维修-苏州泽升精密机械 | LOGO设计_品牌设计_VI设计 - 特创易 | 蔡司三坐标-影像测量机-3D扫描仪-蔡司显微镜-扫描电镜-工业CT-ZEISS授权代理商三本工业测量 | 根系分析仪,大米外观品质检测仪,考种仪,藻类鉴定计数仪,叶面积仪,菌落计数仪,抑菌圈测量仪,抗生素效价测定仪,植物表型仪,冠层分析仪-杭州万深检测仪器网 | 匀胶机旋涂仪-声扫显微镜-工业水浸超声-安赛斯(北京)科技有限公司 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | PC构件-PC预制构件-构件设计-建筑预制构件-PC构件厂-锦萧新材料科技(浙江)股份有限公司 | 无轨电动平车_轨道平车_蓄电池电动平车★尽在新乡百特智能转运设备有限公司 | 展厅设计公司,展厅公司,展厅设计,展厅施工,展厅装修,企业展厅,展馆设计公司-深圳广州展厅设计公司 | 水性漆|墙面漆|木器家具漆|水漆涂料_晨阳水漆官网 | 304不锈钢无缝管_不锈钢管厂家 - 隆达钢业集团有限公司 | 二次元影像仪|二次元测量仪|拉力机|全自动影像测量仪厂家_苏州牧象仪器 | 爱德华真空泵油/罗茨泵维修,爱发科-比其尔产品供应东莞/杭州/上海等全国各地 | 西子馋火锅鸡加盟-太原市龙城酉鼎餐饮管理有限公司 | 抖音短视频运营_企业网站建设_网络推广_全网自媒体营销-东莞市凌天信息科技有限公司 | 杭州火蝠电商_京东代运营_拼多多全托管代运营【天猫代运营】 | 冲锋衣滑雪服厂家-冲锋衣定制工厂-滑雪服加工厂-广东睿牛户外(S-GERT) | 赛尔特智能移动阳光房-阳光房厂家-赛尔特建筑科技(广东)有限公司 | 美国HASKEL增压泵-伊莱科elettrotec流量开关-上海方未机械设备有限公司 | 阻垢剂-反渗透缓蚀阻垢剂厂家-山东鲁东环保科技有限公司 | 扒渣机,铁水扒渣机,钢水扒渣机,铁水捞渣机,钢水捞渣机-烟台盛利达工程技术有限公司 | 辊道窑炉,辊道窑炉厂家-山东艾希尔 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 海鲜池-专注海鲜鱼缸、移动海鲜缸、饭店鱼缸设计定做-日晟水族厂家 | 数显恒温培养摇床-卧式/台式恒温培养摇床|朗越仪器 | 精密模具制造,注塑加工,吹塑和吹瓶加工,EPS泡沫包装生产 - 济南兴田塑胶有限公司 | 塑料撕碎机_编织袋撕碎机_废纸撕碎机_生活垃圾撕碎机_废铁破碎机_河南鑫世昌机械制造有限公司 | 耐磨焊丝,堆焊焊丝,耐磨药芯焊丝,碳化钨焊丝-北京耐默公司 | 建筑资质代办_工程施工资质办理_资质代办公司_北京众聚企服 | wika威卡压力表-wika压力变送器-德国wika代理-威卡总代-北京博朗宁科技 |