单词匹配
来源:互联网 发布:ubuntu server 编辑:程序博客网 时间:2024/05/17 22:40
今天突然看到一到面试题是单词匹配,就想着自己做做看
从网上找了一个常用单词的文件
思考一下,自己的实现方案
- 遍历匹配
- 二分查找法
建立单词数
同时再和Python内置的set比较一下
首先编写计算时间的函数
def time_clock(func): import time import functools @functools.wraps(func) def _(*args,**kwargs): before = time.time() result = func(*args,**kwargs) print 'duration = %s'%(time.time()-before) return result return _
然后是读取文件转为list
words = map(lambda s:s.strip('\n').lower(),open('words.txt').readlines())
由于单个数据不具有代表性,所以我们对列表中所有的元素进行查找计算时长
@time_clockdef match_all(func): import sys sys.stdout.write('func_name:%s '%(func.__name__).ljust(18)) for word in words: if not func(word): print word raise Exception("don't match")
遍历法
def match_word_for(word): for w in words: if w==word: return True return False
最简单,无耻的一种方法,效率也是低到惨无人道。。。。。
二分查找
def match_word_middle(word): start = 0 end = len(words)-1 while start <= end: middle_index = (start+end)/2 middle = words[middle_index] if word == middle: return True elif word < middle: end = middle_index-1 else: start = middle_index+1 return False
不过二分查找之前需要进行排序
words.sort()
单词树
首先是建立单词树
class Char_node(object): def __init__(self,char=0): self.char = char self.children = {} def find_char(self,char): return self.children.get(char,None) def add_char(self,char): node = self.children.get(char,None) if not node: node = Char_node(char) self.children[char] = node return node def __repr__(self): return "<Char_node : %s>"%self.chartree_root = Char_node(0)def add_word(word): node = tree_root for char in word: node = node.add_char(char) else: node.add_char('$')def build_char_tree(words): for word in words: add_word(word)
然后再是在单词树中进行查询,此处我用了一下Python里面的dict数据结构,理因自己实现相关的数据结构,,,,
def match_word_tree(word): node = tree_root for i in range(len(word)): node = node.find_char(word[i]) if not node: return False if i == len(word)-1 and node.children.get('$'): return True return False
我们来比较一下他们的速度快慢
if __name__ == '__main__': build_char_tree(words) words.sort() match_all(match_word_for) match_all(match_word_middle) match_all(match_word_tree)
func_name:match_word_for duration = 0.192780017853func_name:match_word_middle duration = 0.0136761665344func_name:match_word_tree duration = 0.0193219184875[Finished in 0.3s]
可以看得出遍历确实慢的难以忍受!
不过二分查找竟然比单词树还快,比较吃惊
因为单词树的查找次数就是单词的长度而已,二分法的查找次数O(log2n),我的单词表是2000个,按理应该单词树比较快
然后我们再看一下Python自带的数据结构的查询
- set
- list
set
words_set = set(words)def match_word_set(word): return word in words_set
list
def match_word_list(word): return word in words
来个总对比
if __name__ == '__main__': build_char_tree(words) words.sort() match_all(match_word_set) match_all(match_word_list) match_all(match_word_for) match_all(match_word_middle) match_all(match_word_tree)
func_name:match_word_set duration = 0.000779867172241func_name:match_word_list duration = 0.0541019439697func_name:match_word_for duration = 0.183423042297func_name:match_word_middle duration = 0.0140800476074func_name:match_word_tree duration = 0.0185759067535[Finished in 0.4s]
set的速度快的令人发指,据说底层是采用散列表存储
但list的倒是比较慢,但也比单纯的遍历快多了,
总结:在判断一个元素是否在一个序列中的时候用set,速度完全和list不再一个数量级上的
不过我认为单词树仍是个不错的选择,假如单词表非常非常大的情况下~
0 0
- 单词匹配
- 单词匹配
- vi 匹配单词"\<"和"\>"
- Linux vi 匹配单词
- ACM之单词匹配
- 习题单词数字匹配
- perl-单词边界匹配
- 单词匹配算法
- mysql 绝对单词匹配
- Word Pattern--单词匹配
- 插件95:模式匹配单词
- 正则表达式匹配单词\b
- 单词匹配(北大ACM)
- vim中正则表达式匹配单词边界
- 正则表达式匹配单词,不分大小写
- poj 3267(匹配最近的单词)
- Match Whole Words (匹配整个单词)
- gvim 的单词边界匹配问题
- Matrix Chain Multiplication-geeksforgeeks
- nodejs的字符串操作模块
- Android事件处理之处理键盘事件
- OC语言——基本语法和思想
- Ubuntu 14.04安装搜狗输入法
- 单词匹配
- L先生第二天
- shell的简介
- linux下装php5+mysql5+apache 2的笔记
- 2014年终总结
- Html 学习-Html4、XHtml、Html5区别
- 语法笔记_J2SE_Scanner控制台读入
- 写在除夕夜:小马过河辞旧岁,喜气洋洋迎新年
- aspx返回JSON数据