Trie树的python实现(leetcode 208)

 #!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
import pdb reload(sys)
sys.setdefaultencoding('utf-8') class TrieNode(object):
"""Trie节点 Attributes:
_val: 本节点的值(非None即作为结束判断条件)
_next: 后继节点
"""
def __init__(self, value=None):
self._val = value
self._next = {} def set_value(self, value=None):
"""为当前节点设置值
"""
self._val = value def get_value(self):
"""获取当前节点的值
"""
return self._val def set_next(self, key, value=None):
"""为当前节点添加一个后继节点
"""
if key not in self._next:
self._next[key] = TrieNode(value)
return self._next[key] def get_next(self, key):
"""从当前节点获取指定的后继节点
"""
if key not in self._next:
return None
return self._next[key] class Trie(object):
"""Trie树
Attribures:
_root: 根节点
"""
def __init__(self):
# 生成root节点
self._root = TrieNode() def insert(self, word):
"""将一个单词插入trie树
"""
curr = self._root for char in word:
curr = curr.set_next(char)
curr.set_value(True) def search(self, word):
"""检索一个单词是否trie树中存在
"""
curr = self._root
ret = False for i, c in enumerate(word):
curr = curr.get_next(c)
if curr is None:
break
if i + 1 == len(word) and curr.get_value() is True:
ret = True
break
return ret def startsWith(self, prefix):
"""检索trie树中是否有prefix开头的单词
"""
curr = self._root
ret = True for c in prefix:
curr = curr.get_next(c)
if curr is None:
ret = False
break
return ret def main():
trie = Trie()
trie.insert("app")
trie.insert("apple")
print trie.search("app") if __name__ == '__main__':
main()

AC改进算法python实现

 #!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
import pdb reload(sys)
sys.setdefaultencoding('utf-8') class ACTrieNode(object):
"""ACTrie节点 Attributes:
val: 本节点的值(非None即作为结束判断条件)
children: 孩子节点
fail: 失配跳转指针
"""
def __init__(self, value=None):
self.val = value
self.children = {}
self.fail = None def get_next(self, key):
"""从本节点开始,找到children中包含key的节点,如果找不到就返回根节点
"""
if key in self.children.keys():
return self.children[key]
if self.fail is None:
# fail为None就是根节点
return self
return self.fail.get_next(key) class ACTrie(object):
"""ACTrie树 Attribures:
_root: 根节点
"""
def __init__(self):
self._root = ACTrieNode() # 生成root节点 def insert(self, word):
"""将一个单词插入trie树
"""
curr = self._root
for char in word:
if char not in curr.children:
curr.children[char] = ACTrieNode()
curr = curr.children[char]
curr.val = word def update_failure(self):
"""更新failure跳转
"""
bfs_queue = [self._root] # 利用list作为bfs缓存队列 while len(bfs_queue) > 0:
father = bfs_queue.pop(0) # 取出队列头部元素 # BFS遍历父节点的所有子节点,为他们设置failure
for key, child in father.children.items():
bfs_queue.append(child) # 将当前元素放入队列尾部 if father == self._root:
# 当前父节点是root时,其子节点的failure也指向root
child.fail = self._root
else:
# 当前父节点不是root时,其子节点的failure尝试指向"(迭代)父节点的failure的同名子节点"
child.fail = father.fail.get_next(key) def search(self, text):
"""从源字符串中寻找目标字符串
"""
match_set = set()
curr = self._root for char in text:
curr = curr.get_next(char)
# 搜集匹配上的单词
tmp_node = curr
while tmp_node:
if tmp_node.val:
match_set.add(tmp_node.val)
tmp_node = tmp_node.fail
return match_set def main():
trie = ACTrie()
trie.insert("abcd")
trie.insert("ab")
trie.insert("bc")
trie.insert("cf")
trie.insert("cde") trie.update_failure() text = 'abcdefg'
ret = trie.search(text)
print ret if __name__ == '__main__':
main()

字符串模式匹配算法系列(三):Trie树及AC改进算法的更多相关文章

  1. 字符串模式匹配算法系列(二):KMP算法

    算法背景: KMP算法是由Donald Knuth和Vaughan Pratt于1970年共同提出的,而James H.Morris也几乎同时间独立提出了这个算法.因此人们将其称作“克努特-莫里斯-普 ...

  2. 字符串模式匹配算法系列(一):BF算法

    算法背景: BF(Brute Force)算法,是一种在字符串匹配的算法中,比较符合人类自然思维方式的方法,即对源字符串和目标字符串逐个字符地进行比较,直到在源字符串中找到完全与目标字符串匹配的子字符 ...

  3. [转] 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽

    字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 转载自:http://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boy ...

  4. 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽

    字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 ...

  5. 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法

    ref : https://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 KMP ...

  6. 字符串模式匹配算法--BF和KMP详解

    1,问题描述 字符串模式匹配:串的模式匹配 ,是求第一个字符串(模式串:str2)在第二个字符串(主串:str1)中的起始位置. 注意区分: 子串:要求连续   (如:abc 是abcdef的子串) ...

  7. Java数据结构之字符串模式匹配算法---Brute-Force算法

    模式匹配 在字符串匹配问题中,我们期待察看源串 " S串 " 中是否含有目标串 " 串T " (也叫模式串).其中 串S被称为主串,串T被称为子串. 1.如果在 ...

  8. [知识点]Trie树和AC自动机

    // 此博文为迁移而来,写于2015年5月27日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1s8.html 1.前 ...

  9. 字符串模式匹配算法1 - BF和KMP算法

    在字符串S中定位/查找某个子字符串P的操作,通常称为字符串的模式匹配,其中P称为模式串.模式匹配有多种算法,这里先总结一下BF算法和KMP算法. 注意:本文在讨论字符位置/指针/下标时,全部使用C语法 ...

随机推荐

  1. appium常见问题11_小米手机初次启动app,报错255“Requires permission android.permission.WRITE_SECURE_SETTINGS”

    问题: 新申请的测试机到啦,申请机型是小米9.打开开发者模式.USB调试后,连接电脑,准备跑一下自动化脚本.但是在pycharm中点击run后,出现报错,报错code:255,提示“Requires ...

  2. XAMPP【phpmyadmin】外网访问被拒绝解决办法

    问题场景: 在阿里云搭建一个apache服务器,正常访问XAMPP目录下的页面. 服务器本地是可以正常访问的 但是远程 就不可以访问了: 出现这样的画面: 解决方法 1.按照提示找到httpd-xam ...

  3. T1373:鱼塘钓鱼(fishing)

    原题链接:1373:鱼塘钓鱼(fishing) 解题思路: 由于在走路时,鱼的数量不会减少,那我们此时可以先减去路上可能花掉的时间,用剩下的时间来找最多的鱼,然后从左向右走,k枚举能到达的最远的鱼塘, ...

  4. python 装饰器 第十一步:多层装饰器的嵌套

    #第十一步:多层装饰器的嵌套 #装饰器1 def kuozhan1(func): #定义装饰之后的函数 def neweat1(): # 扩展功能1 print('1-----饭前洗手') # 调用基 ...

  5. Qt 程序在 Windows 下的发布

    本文讨论在 Windows 平台下编译成功的 Qt 程序,如何在未配置 Qt 开发环境的 Windows 平台下独立运行的方法. 经过验证发现,在 Ubuntu 平台下编译成功的程序可在未安装 Qt ...

  6. 在controller的action内, 得到用户发过来的请求地址和参数url

    class PController extends Controller{ public function Log() { echo $_SERVER["HTTP_HOST"] . ...

  7. 如何通过HTTP API 调取tushare的股票数据

    长久以来,Tushare一直以固定的Python SDK方式为大家提供数据服务. 虽然在基于Python的数据分析和Python的量化策略开发很方便,但习惯用其他语言的同学们表示了“抗议”,于是在Tu ...

  8. c#静态变量和非静态变量的区别

    静态变量的类型说明符是static.静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成 ...

  9. ubuntu16.04安装LNMP(ubuntu+Nginx+mysql+PHP7.0)

    系统环境: Ubuntu 16.04.2 LTS nginx version: nginx/1.10.3 (Ubuntu) PHP 7.0.22-0ubuntu0.16.04.1 mysql  Ver ...

  10. 24.循环栅栏 CyclicBarrier

    import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * ...