我希望在一组字符串中找到最长的常见后缀,以便在我的自然语言处理项目中检测一些潜在的重要语素。
给定频率K>=2
,在字符串列表中找到K最常见的最长后缀S1,S2,S3...SN
为了简化问题,这里有一些例子:
输入1:
K=2
S=["fireman","woman","businessman","policeman","businesswoman"]
输出1:
["man","eman","woman"]
Explanation1:
如果输出还跟踪每个公共后缀的频率
,将不胜感激{"man":4,"eman":2,"woman":2}
不保证每个单词至少有一个长度的公共后缀,请参阅下面的示例。
输入2:
K=2
S=["fireman","woman","businessman","policeman","businesswoman","apple","pineapple","people"]
输出2:
["man","eman","woman","ple","apple"]
说明2:
“ple”发生3次,“apple”发生2次
任何有效的算法来解决这个问题?
我已经提到了后缀树和广义后缀树算法,但似乎不能很好地适应这个问题。
(顺便说一句,我正在研究中国的NLP项目,这意味着有比英语更多的人物)
答案 0 :(得分:0)
如果你想真正有效率this paper可以提供帮助。该算法为您提供O(n log n)中一组字符串中最频繁(最长)的子串。基本思路如下:
将所有字符串与它们之间的空格连接起来(以后用作分隔符),以便从单个长字符串
在长字符串上构建后缀数组SA
对于后缀数组中的每对相邻条目,检查有多少起始字符等于条目引用的两个后缀(当您到达空格时应该停止)。将相等字符的数量放在另一个数组(称为LCP)中。每个条目LCP [i]指的是长串中位置SA [i-1]和SA [i]的字符串的相等字符数。
浏览LCP,查找计数大于K的连续条目。
来自the paper for3字符串的示例
s1 = bbabab
s2 = abacac
s3 = bbaaa
答案 1 :(得分:0)
一个想法是反转字符串,然后对它们运行尝试。 书中这么简单的技巧。 一旦到达子序列,只需再次反转即可。
例如尝试的结果将是
[nam, name, ...]
将这些颠倒过来会给你最终的答案。
[man, eman, ...]
时间复杂度增加了 + O(n)。