Php运算符,对拼写错误的答案求值为TRUE



我正忙于为一些小学教育学生构建ELO。

ELO中的一些问题是"开放的",因此学生应该在文本框中键入答案。

假设有一个问题的正确答案是"扫描仪"。一个学生打错了字,然后输入"scaner"。我不想把这个答案标记为不正确。

所以我想知道PHP中是否有一个运算符"类似",与MariaDb-Sql中的LIKE或数学中的双"波浪号"相同。

我很确定我的"问题"有解决办法,但我只是渴望学习。

看看这个:

http://php.net/manual/en/function.levenshtein.php

Levenstein算法对于这种精确的场景来说是非常棒的。它可以很好地处理打字错误或大脑放屁的时刻,比如键入"blow"而不是"blue"、姓名等。

Levenstein将返回一个数字。这个数字表示两个单词之间的"距离"。在你的场景中,我会做的是用一个小数字,比如2或3,来达到最大距离。这样一来,如果只需要一个字符校正,那就没问题了。然而,如果单词是"Scanner",并且他们输入"Skammer",那么它实际上不会将其作为有效响应传递。

以下是几个例子:

<?php
$threshold = 2;
$words = array('Scanner', 'Scaner', 'Skanner', 'Skammer', 'Clammer',     'Skaner');
$match = "Scanner";
foreach($words as $word){
    echo levenshtein($match, $word) . "<br>";
}

以上将输出以下内容:

0
1
1
3
4
2

所以你可以看到密切相关的单词和不那么密切相关的词之间的相关性。因此,有了上述阈值,如果我们稍微更改一下代码,我们就可以做这样的事情:

<?php
$threshold = 2;
$words = array('Scanner', 'Scaner', 'Skanner', 'Skammer', 'Clammer', 'Skaner');
$match = "Scanner";
foreach($words as $word){
    if(levenshtein($match, $word) <= $threshold) echo "$word is close enough to $match! <br>";
        else echo "$word is NOT close enough to $match! <br>";
}

我们会得到这样的回应:

Scanner is close enough to Scanner! 
Scaner is close enough to Scanner! 
Skanner is close enough to Scanner! 
Skammer is NOT close enough to Scanner! 
Clammer is NOT close enough to Scanner! 
Skaner is close enough to Scanner! 

请注意"Clammer"与"Scanner"的距离是4。让我稍微解释一下。该距离是为了使单词匹配而必须更改的字符数。所以,"C"必须改变,"L"必须改变并且两个"M"都必须改变。因此,得分为4。

使用时,请考虑"S"one_answers"S"是两个完全不同的字符,因此它绝对区分大小写。我会不区分大小写,以确保像"ScAnNeR"这样的东西不会被标记为错误答案。像这样:

<?php
$threshold = 2;
$words = array('ScAnNeR', 'Scaner', 'Skanner', 'Skammer', 'Clammer', 'Skaner');
$match = "Scanner";
foreach($words as $word){
    if(levenshtein(strtolower($match), strtolower($word)) <= $threshold) echo "$word is close enough to $match! <br>";
        else echo "$word is NOT close enough to $match! <br>";
}

警示语

我强烈建议不要依赖soundex()。看看这个例子:

<?php
$threshold = 2;
$words = array('spectacular', 'spectacle');
$match = "spectacle";
foreach($words as $word){
    if(levenshtein(strtolower($match), strtolower($word)) <= $threshold) echo "$word is close enough to $match! <br>";
        else echo "$word is NOT close enough to $match! <br>";
    echo soundex($word) . "/" . soundex($match) . "<br>";
}

这个例子给出了这样的结果:

spectacular is NOT close enough to spectacle! 
S123/S123
spectacle is close enough to spectacle! 
S123/S123

两个完全不同的单词,甚至听起来都不一样,根据soundex(),它们将是完美的匹配!虽然我认为它对某些应用程序来说是一个有用的函数,但对于这类应用程序来说,它还不够好。这里是另一个例子:

<?php
$threshold = 2;
$words = array('clancy', 'klancy');
$match = "clancy";
foreach($words as $word){
if(levenshtein(strtolower($match), strtolower($word)) <= $threshold) echo "$word is close enough to $match! <br>";
        else echo "$word is NOT close enough to $match! <br>";
    echo soundex($word) . "/" . soundex($match) . "<br>";
}

输出:

clancy is close enough to clancy! 
C452/C452
klancy is close enough to clancy! 
K452/C452

一句话:对于这种应用程序,不要依赖soundex()。你最终只会与它搏斗,并在这个过程中被烧死

您可以使用PHP自带的函数similar_text()。信息可以在这里找到:

http://php.net/manual/en/function.similar-text.php

有趣的是,您通过引用为最后一个参数传递一个变量。所以你会做一些类似的事情:

similar_text($first, $second, $percent)

您可以将$percent指定为接受的阈值。因此,如果它们与X%相似,您可以将其标记为正确。

由于这是一个测试,我个人要求拼写正确,没有拼写错误,但有两种很好的可能性,soundex()和similar_text():

var_dump(
    soundex('scanner') == soundex('scaner')
);

产生true

var_dump(
    strlen('scanner') - similar_text('scanner', 'scaner')
);

产生1,因此您需要决定有多少差异是可以接受的。

另一种更复杂的可能性是levenstein(),尽管根据非常不同的正确答案来决定合适的距离将是一项任务。

最新更新