我需要一个非常有效的算法来执行以下操作:
我必须在任何语言中分离复合词。例如英语。
但是当一个单词由共享最后一个字母和第一个字母的两个单词组成时,就会出现问题。
即第一个单词以第二个单词开头的字母结尾。
所以,我们有一个包含所有可能单词的字典,让它简短:
假设我们想用这个示例性的字典拆分单词“lightshow”:
d = {"light": "Noun, S, N",
"lights": "Noun, P, N",
"how": "Q",
"show": "Noun, S, N",
...}
我的算法现在将单词分成两个列表:
left = []; right = []
for x in range(len(word)-1, 1, -1):
ls = word[:x]; rs = word[x:]
if ls.lower() in d: left.append(ls)
if rs.lower() in d: right.append(rs)
然后我在左边的列表中找到最长的单词,在右边的列表中找到最长的单词。
所以,我知道这个词由哪些词组成,以及它们在复合词中的开始和结束位置。
现在不要担心单词不在字典中、单词不匹配等过度杀伤的情况,我只想向您展示这个想法以及我用这种方法遇到的最大问题。
在整个算法结束时使用这种方法,结果将是:
["lights", "how"]
代替:
["light", "show"]
什么是你能想象到的 Not Acceptable 。
哦,是的,我可以使用以下方法检查字典中是否存在单词显示:
l = ["lights", "how"]
if l[0][-1]+l[1] in d: <repair the list>
但这不切实际,而且我的算法递归地处理由超过 2 个单词组成的单词。
它还处理因大小写等不同而分隔的单词。
这就是为什么我没有完整发布它的原因,因为它很大并且经过优化,因此阅读很多不重要的代码。
哦,是的,我可以通过将最后一个词设为主要来做一些改进。或者在选择哪个先走时比较长度等等。
但并不总是能够通过这些操作做出正确的决定。例如,如果发现最长的单词与多个字母相交,该怎么办?
我想在一个循环中完成所有操作。速度势在必行。
注意:我提供的字典是示范性的。我必须使用的数据集不包含有关单词类型的任何信息。只有它的发音,从中唯一有用的信息可以是说这个词是短还是长。
希望在这里看到一些非常好的想法。请记住,代码必须非常高效。 TTS 实时使用它来发音不在字典中但实际上包含通常发音匹配的单词。 无需向我提供代码,只需将想法付诸实践即可。
最佳答案
在这些情况下,您可能喜欢单词中由连字符算法或字典建议的音节中断。一个好的断字算法会告诉您 light-show
和 data-set
正确地分解了单词。
我不认为绝对在所有情况下都能做到这一点,如果没有某个地方的数据文件明确地将 lightshow
映射到 light + show
并且dataset
到 data + set
等。无论你想出什么算法,总会有出错的地方。
Frank Liang 的断字算法 is available here for Python ,并帮助你的两个例子之一:
>>> hyphenate_word("dataset")
['dataset']
>>> hyphenate_word("lightshow")
['light', 'show']
您可以尝试测试 hyphenate_word()
返回的音节组合(这应该非常有效,因为它在 TeX 中使用),如果没有找到任何东西,请尝试您原来的方法.
它在这些方面做得很好:
[hyphenate_word(x) for x in ["backwoodsman", "whatsoever", "hereupon", "counterclockwise", "notwithstanding", "highwayman "]]
[['back', 'woods', 'man'], ['what', 'so', 'ev', 'er'], ['here', 'upon'], ['coun', 'ter', 'clock', 'wise'], ['notwith', 'stand', 'ing'], ['high', 'way', 'man ']]
A handy list of compound words , 还有一些 triple compound words .
关于Python:将复合词拆分为已知词(来自字典),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33747521/