Trie树的python实现(leetcode 208)

  1. #!/usr/bin/env python
  2. #-*- coding: utf-8 -*-
  3. import sys
  4. import pdb
  5.  
  6. reload(sys)
  7. sys.setdefaultencoding('utf-8')
  8.  
  9. class TrieNode(object):
  10. """Trie节点
  11.  
  12. Attributes:
  13. _val: 本节点的值(非None即作为结束判断条件)
  14. _next: 后继节点
  15. """
  16. def __init__(self, value=None):
  17. self._val = value
  18. self._next = {}
  19.  
  20. def set_value(self, value=None):
  21. """为当前节点设置值
  22. """
  23. self._val = value
  24.  
  25. def get_value(self):
  26. """获取当前节点的值
  27. """
  28. return self._val
  29.  
  30. def set_next(self, key, value=None):
  31. """为当前节点添加一个后继节点
  32. """
  33. if key not in self._next:
  34. self._next[key] = TrieNode(value)
  35. return self._next[key]
  36.  
  37. def get_next(self, key):
  38. """从当前节点获取指定的后继节点
  39. """
  40. if key not in self._next:
  41. return None
  42. return self._next[key]
  43.  
  44. class Trie(object):
  45. """Trie树
  46. Attribures:
  47. _root: 根节点
  48. """
  49. def __init__(self):
  50. # 生成root节点
  51. self._root = TrieNode()
  52.  
  53. def insert(self, word):
  54. """将一个单词插入trie树
  55. """
  56. curr = self._root
  57.  
  58. for char in word:
  59. curr = curr.set_next(char)
  60. curr.set_value(True)
  61.  
  62. def search(self, word):
  63. """检索一个单词是否trie树中存在
  64. """
  65. curr = self._root
  66. ret = False
  67.  
  68. for i, c in enumerate(word):
  69. curr = curr.get_next(c)
  70. if curr is None:
  71. break
  72. if i + 1 == len(word) and curr.get_value() is True:
  73. ret = True
  74. break
  75. return ret
  76.  
  77. def startsWith(self, prefix):
  78. """检索trie树中是否有prefix开头的单词
  79. """
  80. curr = self._root
  81. ret = True
  82.  
  83. for c in prefix:
  84. curr = curr.get_next(c)
  85. if curr is None:
  86. ret = False
  87. break
  88. return ret
  89.  
  90. def main():
  91. trie = Trie()
  92. trie.insert("app")
  93. trie.insert("apple")
  94. print trie.search("app")
  95.  
  96. if __name__ == '__main__':
  97. main()

AC改进算法python实现

  1. #!/usr/bin/env python
  2. #-*- coding: utf-8 -*-
  3. import sys
  4. import pdb
  5.  
  6. reload(sys)
  7. sys.setdefaultencoding('utf-8')
  8.  
  9. class ACTrieNode(object):
  10. """ACTrie节点
  11.  
  12. Attributes:
  13. val: 本节点的值(非None即作为结束判断条件)
  14. children: 孩子节点
  15. fail: 失配跳转指针
  16. """
  17. def __init__(self, value=None):
  18. self.val = value
  19. self.children = {}
  20. self.fail = None
  21.  
  22. def get_next(self, key):
  23. """从本节点开始,找到children中包含key的节点,如果找不到就返回根节点
  24. """
  25. if key in self.children.keys():
  26. return self.children[key]
  27. if self.fail is None:
  28. # fail为None就是根节点
  29. return self
  30. return self.fail.get_next(key)
  31.  
  32. class ACTrie(object):
  33. """ACTrie树
  34.  
  35. Attribures:
  36. _root: 根节点
  37. """
  38. def __init__(self):
  39. self._root = ACTrieNode() # 生成root节点
  40.  
  41. def insert(self, word):
  42. """将一个单词插入trie树
  43. """
  44. curr = self._root
  45. for char in word:
  46. if char not in curr.children:
  47. curr.children[char] = ACTrieNode()
  48. curr = curr.children[char]
  49. curr.val = word
  50.  
  51. def update_failure(self):
  52. """更新failure跳转
  53. """
  54. bfs_queue = [self._root] # 利用list作为bfs缓存队列
  55.  
  56. while len(bfs_queue) > 0:
  57. father = bfs_queue.pop(0) # 取出队列头部元素
  58.  
  59. # BFS遍历父节点的所有子节点,为他们设置failure
  60. for key, child in father.children.items():
  61. bfs_queue.append(child) # 将当前元素放入队列尾部
  62.  
  63. if father == self._root:
  64. # 当前父节点是root时,其子节点的failure也指向root
  65. child.fail = self._root
  66. else:
  67. # 当前父节点不是root时,其子节点的failure尝试指向"(迭代)父节点的failure的同名子节点"
  68. child.fail = father.fail.get_next(key)
  69.  
  70. def search(self, text):
  71. """从源字符串中寻找目标字符串
  72. """
  73. match_set = set()
  74. curr = self._root
  75.  
  76. for char in text:
  77. curr = curr.get_next(char)
  78. # 搜集匹配上的单词
  79. tmp_node = curr
  80. while tmp_node:
  81. if tmp_node.val:
  82. match_set.add(tmp_node.val)
  83. tmp_node = tmp_node.fail
  84. return match_set
  85.  
  86. def main():
  87. trie = ACTrie()
  88. trie.insert("abcd")
  89. trie.insert("ab")
  90. trie.insert("bc")
  91. trie.insert("cf")
  92. trie.insert("cde")
  93.  
  94. trie.update_failure()
  95.  
  96. text = 'abcdefg'
  97. ret = trie.search(text)
  98. print ret
  99.  
  100. if __name__ == '__main__':
  101. 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. 同时连接gitlab和github

    ---恢复内容开始--- 原文地址:https://juejin.im/post/5ac0cf356fb9a028df22c246 1. 分别生成gitlab和github的ssh key 生成第一个 ...

  2. Linux(Ubuntu)常用命令(五)—— vi/vim常用操作

    vi/vim常用命令 vim其实就是vi的升级版,vi里的所有命令vim里都可以用,一般使用来说几乎没什么差别. 注:本篇文章区分大小写! vi / vim三级模式的关系: 命令行模式 任何时候,不管 ...

  3. 关于tomcat中的三个端口的作用及其相关细节

    [一]端口内容 tomcat的端口号相关信息: Tomcat admin port——管理端口,允许你远程配置tomcat HTTP——正常的http协议 AJP——Apache JServ Prot ...

  4. docker-compos联合两个容器

    使用网络 ' services: web: image: http networks: - myappnet1 worker: image: http networks: - myappnet2 db ...

  5. 模拟javaWeb责任链的设计

    这篇文章介绍了责任链模式的应用:本文介绍如果自己实现一个责任链 定义请求和响应信息 简单定义请求类Request(封装一个字符串) public class Request { String requ ...

  6. Model-View-ViewModel (MVVM) Explained 转摘自:http://www.wintellect.com/blogs/jlikness/model-view-viewmodel-mvvm-explained

    The purpose of this post is to provide an introduction to the Model-View-ViewModel (MVVM) pattern. W ...

  7. centos7 部署镜像仓库 harbor步骤详解

    一.基础设置  1.1 安装vim.wget yum install -y vim wget  1.2 卸载home.扩大root 如果考虑镜像仓库是给研发团队使用,需要配置较大容量的,因为cento ...

  8. linux随笔-02

    部署虚拟环境安装linux系统以及一些常用命令 工具: VmwareWorkStation  12.0——虚拟机软件(必需) RedHatEnterpriseLinux [RHEL]7.0——红帽操作 ...

  9. Codeforces 364D 随机算法

    题意:给你一个序列,定义ghd为一个序列中任意n / 2个数的gcd中最大的那个,现在问这个序列的ghd为多少. 思路:居然是论文题...来自2014年国家集训队论文<随机化算法在信息学竞赛中的 ...

  10. SpringMvc返回给前端数据@ResponseBody响应体【支持Ajax】

    1).在Controller中写 //@ResponseBody响应体是jackson包提供的 用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格 ...