【发布时间】:2018-04-17 06:35:33
【问题描述】:
我希望测试 MDLD 的性能,以便将一些浏览器内的字符串比较集成到 Web 应用程序中。用例涉及比较字符串,例如“300mm, Packed Wall”和“Packed Wall - 300mm”,所以我一直在寻找模糊字符串匹配,它对标点符号和拼写错误有一定的容忍度,并且允许块字符换位。
我无法在线找到 Javascript 的实现。我在CSIRO's Taxamatch Wiki 找到了一个为PL/SQL 编写的版本。
这是我将代码转换为 JS 的尝试;基本函数的结果似乎相当准确,但是,块转置计算并没有给出预期的结果。例如。 “Hi There”与“There Hi”返回“6”,无论块限制设置为多少。
如果有人知道一个可行的实现,你能指点我吗?或者,我的改编有什么问题,或者源代码本身有什么问题?我所做的唯一主要更改是在源似乎使用整数除法的两个实例中使用“Math.ceil()”,这总是会占用地板——这会导致输入的奇怪问题导致 1 个字符串- 但似乎并没有影响我测试过的其他案例的行为。
function mdld(str1, str2, block_lim)
{
mycol = [];
cost = 0;
len1 = str1.length;
len2 = str2.length;
if( str1 === str2 )
return 0;
else if ( len1 === 0 || len2 === 0 )
return Math.max(len1, len2);
else if ( len1 === 1 && len2 === 1 && str1 !== str2 )
return 1;
else
{
// Temporary strings which will be pre-processed
// Speeds up calcs & retains correct measurement
temp1 = str1;
temp2 = str2;
// Trim any common initial characters
while ( temp1.substr(0,1) === temp2.substr(0,1) )
{
temp1 = temp1.substr(1, temp1.length);
temp2 = temp2.substr(1, temp2.length);
}
// Trim any trailing characters
while ( temp1.substr(-1,1) === temp2.substr(-1,1) )
{
temp1 = temp1.substr(0,temp1.length-1);
temp2 = temp2.substr(0,temp2.length-1);
}
len1 = temp1.length;
len2 = temp2.length;
// Calc Levenshtein Distance
if (len1 === 0 || len2 === 0)
return Math.max(len1, len2);
else if (len1 === 1 && len2 === 1 && str1 !== str2)
return 1;
else
{
// Create columns
var s, t;
for(s = 0; s <= len1; s++)
mycol[s] = [];
// Enter values into leftmost column
for(t = 0; t <= len2; t++)
mycol[0][t] = t;
// Populate remaining columns
for(s = 1; s <= len1; s++)
{
mycol[s][0] = s;
// Populate first row (each cell of one column)
for(t = 1; t <= len2; t++)
{
//Calculate cost
if (temp1.substr(s-1,1) === temp2.substr(t-1,1))
cost = 0;
else
cost = 1;
// extension to cover multiple character transpositions
// that includes calculation of original Levenshtein distance when no transposition
tempBlockLen = Math.min( Math.ceil(len1/2), Math.ceil(len2/2), !block_lim ? 1 : block_lim );
while (tempBlockLen >= 1)
{
if ((s >= tempBlockLen * 2) &&
(t >= tempBlockLen * 2) &&
(temp1.substr(s-tempBlockLen*2, tempBlockLen) === temp2.substr(t-tempBlockLen, tempBlockLen)) &&
(temp1.substr(s-tempBlockLen, tempBlockLen) === temp2.substr(t-tempBlockLen*2, tempBlockLen)))
{
// Transposition found
mycol[s][t] = Math.min( mycol[s][t-1] + 1,
mycol[s-1][t] + 1,
mycol[s-tempBlockLen*2][t-tempBlockLen*2] + cost + tempBlockLen - 1 );
tempBlockLen = 0;
}
else if (tempBlockLen === 1)
{
// No Transposition
mycol[s][t] = Math.min( mycol[s][t-1] + 1,
mycol[s-1][t] + 1,
mycol[s-1][t-1] + cost );
}
tempBlockLen = tempBlockLen - 1;
}
}
}
}
return mycol[len1][len2];
}
}
【问题讨论】:
-
@Jamiec,谢谢你,不,我没有。不完全是我正在寻找的东西。如果我理解正确,使用该响应中的代码,我可以增加字符转置的权重;但是,我不希望单词的变位词具有更高的权重,它需要保留小节的顺序。
标签: javascript stored-procedures levenshtein-distance