将单词拼写错误的位置放置点

时间:2009-12-31 15:16:28

标签: php algorithm levenshtein-distance

我正在用PHP创建一个网络应用程序,人们可以尝试翻译他们需要在学校学习的单词。

例如,有人需要用英语将荷兰语'weer'翻译为'weather',但不幸的是他输入'是否'。因为他几乎输入了正确的单词,我想再给他一次尝试,在他犯错误的地方点'.':

Language A:   weer
Language B:   weather
Input:        whether
Output:       w..ther

或者,例如

Language A:   fout
Language B:   mistake
Input:        mitake
Output:       mi.take

或者:

Language A:   echt
Language B:   genuine
Input:        genuinely
Output:       genuinely (almost good, shorten the word a little bit)

但是,如果输入与所需的翻译差别太大,我不希望获得像........

这样的输出

我听说Levenshtein的距离很远,我想我需要的算法与那个算法非常相似,但我不知道如何在正确的位置放置点,而不是回显要做多少操作。

那么,如何在有人犯错误的地方以点的形式返回拼写错误的单词呢?

3 个答案:

答案 0 :(得分:4)

首先,看看Levenshtein algorithm on wikipedia。 然后继续查看文章页面上的示例和结果矩阵d

                *k*     *i*     *t*     *t*     *e*     *n*
        >0       1       2       3       4       5       6 
*s*      1      >1       2       3       4       5       6 
*i*      2       2      >1       2       3       4       5 
*t*      3       3       2      >1       2       3       4 
*t*      4       4       3       2      >1       2       3 
*i*      5       5       4       3       2      >2       3 
*n*      6       6       5       4       3       3      >2 
*g*      7       7       6       5       4       4      >3 

距离位于矩阵的右下角,d [m,n]。但是从那里开始 现在可以跟踪回溯矩阵左上角的最小步骤d [1,1]。您可以在每个步骤中向左,向左或向上,无论哪个路径最小化。 在上面的示例中,您将找到标记为“>”的路径体征:

  s i t t i n g      k i t t e n
0 1 1 1 1 2 2 3    0 1 1 1 1 2 2 3
  ^       ^   ^      ^       ^   ^
  changes in the distance, replace by dots

现在你可以找到距离变化的最小路径d [i,j](在上面的例子中用^标记),以及你在第一个(或第二个)单词中放入点的字母位置i(或分别为j)。

结果:

  s i t t i n g      k i t t e n
  ^       ^   ^      ^       ^   ^
  . i t t . n .      . i t t . n . 

答案 1 :(得分:3)

您正在寻找的术语称为“编辑距离”。使用Levenshtein distance之类的东西会告诉你将一个字符串转换成另一个字符串所需的操作数(插入,删除,替换等)。

Here is a list of other "editing distance" algorithms

一旦你确定一个单词“足够接近”(即它没有超过所需编辑的某个阈值),你就可以显示编辑需要发生的位置(通过显示点)。

那么你怎么知道在哪里放点?

关于“Levenshtein距离”的有趣之处在于它使用M x N矩阵,每个轴上有一个单词(参见Levenshtein article中的样本矩阵)。创建矩阵后,您可以确定哪些字母需要“其他编辑”才能正确。那是你放点的地方。如果这封信要求“无需额外编辑”,则只需打印该字母即可。很酷。

答案 2 :(得分:0)

我认为你需要做一个多步骤的过程而不仅仅是Levenshtein。首先,我会检查输入字是否是目标字的一种形式。这将抓住你的第三个例子,也不用担心添加点。您还可以使用此步骤来捕获同义词。下一步是检查两个字符串的长度差异。

如果差异为0,您可以使用字母进行字母比较以放置点。如果你不想显示所有的点,那么你应该保持一个点的计数,一旦超过限制显示一些错误信息。 (抱歉这是不正确的)

如果差异显示输入较长,则需要检查要删除的字母才能解决问题。在这里,您可以使用Levenshtein看看它们距离太远,如果距离太远,则显示您的错误消息,如果它在范围内,您将需要反向执行Levenshtein的步骤并以某种方式标记更改。不确定如何显示信件是否需要删除。

如果差异显示输入较短,您可以使用Levenshtein距离来查看两个单词是否足够接近或显示错误。然后再反向执行步骤,为插入添加点和替换点。

实际上,最后两个步骤可以合并为一个贯穿算法的函数,并记住插入删除或替换,并相应地更改输出。