Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 给出一个单词列表,识别长度为4或更大的所有相同子字符串_Python_Algorithm_Counter_Frequency - Fatal编程技术网

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

假设我有一个外来词列表:

  • 伊利库瓦
  • 阿利库瓦
  • 尼利文迪沙
  • 阿纳芬迪沙
  • 图纳索马
  • 郁金香瘤
  • 我想在这个单词列表中找出单词中常见的长度为4或更大的子字符串。例如,“kuwa”、“fundisha”和“soma”都属于这一类

    然后,当我重新进行频率分析时:

    cnt = Counter()
    for lines in list:
        cnt[words]
    print cnt.most_common(2000)
    
    我希望将这些子字符串计算为它们在整个列表中出现的次数……这样:print cnt.most_common(3)的最终输出将类似于

  • 库瓦-2
  • 芬迪莎-2
  • 索马-2
  • 伊利库瓦-1 …等等

  • 不过,我完全不知道该怎么做。有什么想法吗?

    如果效率很重要的话,我相信你需要一个

    如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]