活跃农民
- 积分
- 350
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2014-5-11
- 最后登录
- 1970-1-1
|
用了trie合并字典中的prefix
预处理S,把a~z在S中的index按照先后次序存进charList中
idxs表示目前各个char的index
每选一个char需要把其他所有char的index增加使得其他的char index都比所选char index的还大
另外写了brute force的方法,和test的method
跑出来brute force的比较快啊。。。
10 个 case 的数据
trie time: 5.45
brute time: 0.08
trie time: 3.86
brute time: 0.05
trie time: 3.96
brute time: 0.05
trie time: 5.05
brute time: 0.07
trie time: 3.90
brute time: 0.05
trie time: 4.13
brute time: 0.05
trie time: 3.64
brute time: 0.05
trie time: 5.44
brute time: 0.07
trie time: 3.43
brute time: 0.04
trie time: 4.07
brute time: 0.05
单位是秒
- from random import choice, randint
- import string
- from time import time
- def dictSearch(S, words):
- global ans
- trie = Trie()
- for word in words:
- trie.insert(word)
- charList = [list() for _ in range(26)]
- for i, c in enumerate(S):
- charList[ord(c) - ord('a')].append(i)
- idxs = [0] * 26
- ans = ""
- def dfs(node, cur_idxs):
- global ans
- if node is None:
- return
- if node.isword and len(node.word) > len(ans):
- ans = node.word
- for i, child in enumerate(node.childs):
- if child and cur_idxs[i] < len(charList[i]):
- idxs = list(cur_idxs)
- for j in range(26):
- while idxs[j] < len(charList[j]) and charList[j][idxs[j]] < charList[i][idxs[i]]:
- idxs[j] += 1
- dfs(child, idxs)
- return
- dfs(trie.root, idxs)
- return ans
- class Trie:
- def __init__(self):
- self.root = TrieNode()
- def insert(self, word):
- i = self.root
- for c in word:
- t = ord(c) - ord('a')
- if i.childs[t] == None:
- i.childs[t] = TrieNode()
- i = i.childs[t]
- i.isword = True
- i.word = word
- class TrieNode:
- def __init__(self):
- self.isword = False
- self.childs = [None] * 26
- self.word = None
- def brute(S, words):
- ans = ''
- for word in words:
- next = 0
- for c in word:
- next = S.find(c, next)
- if next == -1:
- break
- else:
- if len(word) > len(ans):
- ans = word
- return ans
- def test():
- for i in range(10):
- S = ''.join(choice(string.ascii_lowercase) for _ in range(randint(500,1000)))
- words = [''.join(choice(string.ascii_lowercase) for _ in range(randint(10,20))) for _ in range(randint(10000, 20000))]
- words.sort()
- now = time()
- trie_result = dictSearch(S, words)
- print('trie time: %.2f' % (time() - now))
- now = time()
- brute_result = brute(S, words)
- print('brute time: %.2f' % (time() - now))
- assert(trie_result == brute_result)
复制代码 |
|