我需要用*来审查所有出现的单词列表。我在列表中有大约400个单词,它会受到大量流量的影响,所以我想让它变得非常高效。这样做的有效算法/数据结构是什么?最好是Python中的东西。
示例:
答案 0 :(得分:1)
不区分大小写的trie支持的集合实现可能符合要求。对于每个单词,您只需处理最少的字符。例如,你只需要处理“zoo”这个词的第一个字母就知道你的列表中没有这个词(假设你没有'z'咒骂)。
然而,这不是与python一起打包的。您可以通过简单的字典解决方案观察到更好的性能,因为它是用C实现的。
答案 1 :(得分:0)
(1)设P是要审查的短语集。
(2)预计算H = {h(w)| P中的p,w是p}中的一个单词,其中h是一个合理的散列函数。
(3)对于输入的每个单词v,测试h中的h(v)是否
(4)如果h(v)不在H中,则发出v。
(5)如果H中的h(v),则返回任何天真的方法,检查v和后面的单词是否形成P中的短语。
步骤(5)不是问题,因为我们假设P与输入量相比(非常)小。步骤(3)是O(1)操作。
答案 2 :(得分:0)
您可能希望为其他人计算基于正则表达式的解决方案。我之前在文本中使用了类似的正则表达式替换一到三千个单词来将短语更改为链接,但我并没有将这些页面提供给很多人。
我接受一组单词(它可能是短语),并在其中形成一个正则表达式,因为'\ b'而将它们作为文本中的完整单词匹配。
如果你有一个字典映射到他们的清理版本的话,那么你可以使用它。为了方便起见,我只是用'*'换掉每个奇怪的字母。
清理程序函数只返回任何匹配的发誓单词的清理版本,并在文本的正则表达式替换调用中使用,以返回已清理的版本。
import re
swearwords = set("Holy Cow".split())
swear = re.compile(r'\b(%s)\b' % '|'.join(sorted(swearwords, key=lambda w: (-len(w), w))))
sanitized = {sw:''.join((ch if not i % 2 else '*' for i,ch in enumerate(sw))) for sw in swearwords}
def sanitizer(matchobj):
return sanitized.get(matchobj.group(1), '????')
txt = 'twat prick Holy Cow ... hell hello shitter bonk'
swear.sub(sanitizer, txt)
# Out[1]: 'twat prick H*l* C*w ... hell hello shitter bonk'
您可能希望使用re.subn和count参数来限制完成的替换次数,如果它有太多的亵渎,则拒绝整个文本:
maxswear = 2
newtxt, scount = swear.subn(sanitizer, txt, count=maxswear)
if scount >= maxswear: newtxt = 'Ouch my ears hurt. Please tone it down'
print(newtxt)
# 'Ouch my ears hurt. Please tone it down'
答案 3 :(得分:0)
Trie
可能是您需要的东西,实际上,您应该使用Aho–Corasick string matching algorithm。不仅仅是一个特里。
对于每个字符串,比如说您需要处理的S
,时间复杂度约为O(len(S))
。我的意思是,线性
您最初需要构建自动机,时间复杂度为O(sigma(len(words)))
,空间复杂度约为(不太经常)O(52*sigma(len(words)))
此处 52 表示字母表(我把它当作['a'..'z', 'A'..'Z']
)。而且你需要只做一次(或每次系统启动时)。
答案 4 :(得分:-1)
如果你想要表现我会建议:
我知道这不是很好而且我只是建议采用这种方法,因为流量高的情况下,对列表中的每个单词进行循环会对性能产生巨大的负面影响。< / p>
希望有所帮助,或者至少可以为您解决如何解决问题的想法。