Levenshtein距离与插入和替换的非统一成本:

时间:2016-10-12 15:15:57

标签: c++ algorithm levenshtein-distance edit-distance

我一直在尝试在C ++中实现一个levenshtein距离函数,它根据替换或插入的字符为替换和插入赋予不同的权重。

费用是根据qwerty键盘上按键的距离计算的。例如,在标准编辑距离算法中,google,hoogle和zoogle之间的距离是相同的;我想要的是这些距离的不同。像谷歌这样的东西 - > hoogle = 1,google - > zoogle = 4,hoogle - > zoogle = 5.

我使用矩阵跟踪Wikipedia algorithm进行记忆,并用c ++实现。这是我的功能。

int levDist(string s, string t) {

    int i,j,m,n,temp,subsitutionCost, deletionCost, insertionCost, keyDist;
    deletionCost = 1;

    m = s.length();
    n = t.length();
    int d[m+1][n+1];

    for(i=0;i<=m;i++)
        d[i][0] = i;
    for(j=0;j<=n;j++)
        d[0][j] = j;

    for (j=1;j<=n;j++)
    {
        for(i=1;i<=m;i++)
        {
            // getKeyboardDist(char a, char b) gives distance b/w the two keys
            keyDist = getKeyboardDist(s[i-1],t[j-1]); 

            subsitutionCost = (s[i-1] == t[j-1]) ? 0 : keyDist;

            // this line is the one i think the problem lies in
            insertionCost = (i > j) ? getKeyboardDist(s[i-1],t[j-2]) : getKeyboardDist(s[i-2],t[j-1]);


            insertionCost = insertionCost ? insertionCost : 1;

            d[i][j] = min((d[i-1][j]   + deletionCost),
                      min((d[i][j-1]   + insertionCost),
                          (d[i-1][j-1] + subsitutionCost)));`
        }
    }
    return d[m][n];
}

现在替换工作正常我相信,但问题是插入。我不知道如何找到哪些字符来获得插入之间的距离。特别是当插入位于字符串的开头或结尾时的情况。

如果有任何其他需要,请与我联系。

提前致谢。

2 个答案:

答案 0 :(得分:1)

您尝试做的事情对替换有意义。你假设一个试图敲击钥匙X的人更有可能通过撞击物理上靠近X的钥匙而不是远处的钥匙来犯错误。

它对插入和删除没有多大意义,因为敲击额外键(插入错误)或跳过键敲击(删除错误)的行为与键没有任何明显的关系距离。

你有可能被“距离”的两种不同含义误导。在这里玩。在插入/替换/删除操作中测量字符串之间的Levenshtein距离。键盘距离是物理分离。这些是苹果和橘子,恰好用同一个词来描述。他们不能很好地混合。

您正在尝试为Levenshtein操作确定权重。密钥之间的物理距离为替换提供了合理的权重。

插入和删除的权重 - 每个只涉及一个字符 - 与物理分离没有任何明显的关系。

您真正想要的是关于人们实际插入和删除哪些键的频率数据。你给出了最常见的相对较低的权重和最不常见的较高权重。

@ user6952491的想法是重复上一个密钥可能是高频插入错误的优点,但很难将其扩展到完整的加权方案。

如果你处于猜测的情绪中,你可以假设在键盘中间附近错误地插入一个键比在边缘处更容易插入一个键。说fj获得最低权重和~之类的字符,这些字符会被移位并且在键盘极端处获得较高的权重,因为您不太可能做出物理动作不假思索地输入它们。

我会留给你一个关于删除的类似猜测。

对于一般打字,我的猜测是,键盘错误至少与拼写错误概念一样,与物理错误有关。即,人们会输入&#34;收到&#34;因为他们忘记了规则&#34;我在e之前除了c之外,&#34;不是因为i相对于e的键盘位置。

其他类型的打字,例如计算机代码,可能会有完全不同的错误模式。想到被遗忘的分号!那些重量很轻!

因此,我几乎可以肯定,现代拼写检查程序提供的建议植根于机器学习算法,这些算法可以从数千人过去在类似任务中犯下的错误中得出结论,而不是简单的基于键盘距离。

答案 1 :(得分:0)

如果您将所有键放在图表中,您可以轻松计算它们的距离。如果你用简单的neighbor listmatrix来构建你自己插入的值,那就更容易了。

在我看来插入应该算作右边和左边(如果存在)字母+ 1之间的最小距离,因为google和gooogle非常相似,但google和gowogle非常相似。因此google-&gt; googl:= 7。