我一直在尝试为以下问题提出有效的解决方案。我有一个包含变音符号的单词的排序列表,我希望能够在不使用变音符号的情况下进行搜索。所以例如我想使用'kriz'匹配'kříž'。经过一番头脑风暴后,我想出了以下内容,我想问你,更有经验(或聪明)的,无论是最优还是有更好的解决方案。我正在使用Python,但问题与语言无关。
首先,我提供了那些具有一些变音兄弟姐妹的角色的映射。所以在捷克的情况下:
cz_map = {'a' : ('á',), ... 'e' : ('é', 'ě') ... }
现在,我可以轻松地在输入中创建单词的所有变体。所以对于'喇嘛',我得到:['lama','láma','lamá','lámá']。我已经可以使用它来搜索与这些排列相匹配的单词,但是当涉及像'nepredvidatelny'这样的单词(不可预测)时,会得到13824个排列。虽然我的笔记本电脑上有一个闪亮的英特尔i5标志,但这对我的品味来说太天真了。
这是我提出的一项改进。我正在使用的单词词典具有二进制搜索的变体,用于前缀匹配(在最低索引上返回带有匹配前缀的单词),在这种情况下非常有用。我从第一个字符开始,在字典中搜索它的前缀存在,如果它在那里,我将它堆叠起来,为将要测试的下一个字符附加到所有这些堆叠序列。这样我只传播那些导致匹配的字符串。这是代码:
def dia_search(word, cmap, dictionary):
prefixes = ['']
for c in word:
# each character maps to itself
subchars = [c]
# and some diacritical siblings if they exist
if cmap.has_key(c):
subchars += cmap[c]
# build a list of matching prefixes for the next round
prefixes = [p+s for s in subchars
for p in prefixes
if dictionary.psearch(p+s)>0]
return prefixes
这项技术给出了非常好的结果,但它可能会更好吗?或者是否有一种技术不需要像这种情况下的字符映射?我不确定这是否相关,但我使用的字典没有按任何整理规则排序,所以序列是'a','z','á'不是'a','á','z'人们可以期待。
感谢所有评论。
编辑:我无法创建任何辅助预先计算的数据库,这些数据库将是原始数据库的副本但没有变音符号。假设原始数据库太大而无法复制。
答案 0 :(得分:1)
仅使用标准库(str.maketrans
和str.translate
),您可以这样做:
intab = "řížéě" # ...add all the other characters
outtab = "rizee" # and the characters you want them translated to
transtab = str.maketrans(intab, outtab)
strg = "abc kříž def ";
print(strg.translate(transtab)) # abc kriz def
这是for python3。
对于python 2,您需要:
from string import maketrans
transtab = maketrans(intab, outtab)
# the rest remains the same
答案 1 :(得分:0)
查看Unidecode使用哪个实际上可以将变音符号转换为最接近的ascii。 e.g: - unidecode(u'kříž')
答案 2 :(得分:0)
如上所述,您要做的是将您的unicode单词(包含变音符号)翻译成最接近的标准24字母字母版本。
实现此目的的一种方法是创建具有相应翻译的第二个单词列表(具有相同大小的原始单词)。然后在翻译列表中执行查询,并在匹配后查找原始列表中的相应位置。
或者,如果您可以更改原始列表,您可以就地翻译所有内容并删除重复项。