Python 给出一个单词列表,识别长度为4或更大的所有相同子字符串
假设我有一个外来词列表:Python 给出一个单词列表,识别长度为4或更大的所有相同子字符串,python,algorithm,counter,frequency,Python,Algorithm,Counter,Frequency,假设我有一个外来词列表: 伊利库瓦 阿利库瓦 尼利文迪沙 阿纳芬迪沙 图纳索马 郁金香瘤 我想在这个单词列表中找出单词中常见的长度为4或更大的子字符串。例如,“kuwa”、“fundisha”和“soma”都属于这一类 然后,当我重新进行频率分析时: cnt = Counter() for lines in list: cnt[words] print cnt.most_common(2000) 我希望将这些子字符串计算为它们在整个列表中出现的次数……这样:print cnt.most
cnt = Counter()
for lines in list:
cnt[words]
print cnt.most_common(2000)
我希望将这些子字符串计算为它们在整个列表中出现的次数……这样:print cnt.most_common(3)的最终输出将类似于
不过,我完全不知道该怎么做。有什么想法吗?如果效率很重要的话,我相信你需要一个 如wiki中所示,使用后缀数组可以计算O(m+logN)中任何子字符串的出现次数,其中m是子字符串的长度,N是所有单词的总长度
然而,您仍然需要枚举每个单词的所有子字符串。我不认为在最坏的情况下O(N*N)枚举是可以避免的。但是使用dict()避免对重复的子字符串进行多次检查肯定会提高平均情况下的性能。您已经在使用
计数器了,因此缺少的只是生成任何给定字符串的子字符串的方法。如果该位位于某个函数中,该函数采用字符串和子字符串的最小长度,则在itertools.chain
的帮助下,您的计数逻辑可以是一行:
cnt = Counter(chain.from_iterable(substrings(line, 4) for line in lines))
cnt.most_common(2000)
剩下的问题是如何生成这些子字符串。最简单的方法是循环子字符串的可能大小,然后循环字符串并返回从字符串中每个连续位置开始的片段,并具有给定的长度(但由于Python中的片段采用起始索引和结束索引,因此我们需要执行一些片段算术以实现这一点):
第一个结果不应该是像Uwa-2一样吗?妈的,蒂姆,你说得对。这肯定是个问题,因为“kuwa”是动词的词根,“li”只是表示过去时。也许必须有一些条件来忽略“li”、“na”、“ta”和“ji”[过去、现在、未来和自反],除非它们像ilipa一样加倍,在这种情况下,“lipa”是动词根。看起来你应该研究自然语言处理器,而不是正则表达式。人类语言不适合正则表达式…我理解这是如何工作的,但我不确定如何让cnt.most_common(2000)打印实际字符串,而不是迭代器对象。有什么想法吗?@Parseltongue使用chain.from_iterable
而不是chain
;我已经在我的回答中解决了这个问题。
def substrings(s, min_length=1):
for length in range(min_length, len(s)+1):
for start in range(len(s) - min_length + 1):
yield s[start:start+length]