wykrywa różnice między dwoma łańcuchami za pomocą Javascript
W Javascript chcę sprawdzić, ile jest różnic między dwoma łańcuchami.
Coś jak:
var oldName = "Alec";
var newName = "Alexander";
var differences = getDifference(oldName, newName) // differences = 6
Wszelkie litery dodane do nazwy powinny być liczone jako jedna zmiana na literę.Zmiana litery powinna być liczona jako zmiana na literę. Zamieniam dwalitery powinny się liczyć jako dwie zmiany, ponieważ każda naprawdę się zmienialeter.Jednak przesunięcie litery i wstawienie innej powinno się liczyć tylko jako jedna zmiana.
Na przykład:
Zmiana „Alex” na „Alexander” to 5 zmian, ponieważ dodano 5 liter
Zmiana „Alexa” na „Allex” byłaby tylko jedną zmianą, ponieważ dodałeś „l” i przesunął resztę, ale ich nie zmienił
Zmiana „Alexander” na „Allesander” to 2 zmiany (dodanie „l” i zmiana „x” na „s”).
Mogę podzielić każdą nazwę na tablicę liter i porównać je w prosty sposóbjsFiddle z poniższą funkcją:
function compareNames(){
var oldName = $('#old').val().split("");
var newName = $('#new').val().split("");
var changeCount = 0;
var testLength = 0;
if(oldName.length > newName.length){
testLength=oldName.length;
}
else testLength=newName.length;
for(var i=0;i<testLength;i++){
if(oldName[i]!=newName[i]) {
changeCount++;
}
}
alert(changeCount);
}
Ale jak mogę wyjaśnić przesunięcie liter nie licząc się jako zmianę?
Aktualizacja: Oto jak to działa
Odległość Levenshteina było dokładnie to, czego potrzebowałem. Dzięki Peter!
$(function () {
$('#compare').click(function () {
var oldName = $('.compare:eq(0)').val();
var newName = $('.compare:eq(1)').val();
var count = levDist(oldName, newName);
$('#display').html('There are ' + count + ' differences present');
});
});
function levDist(s, t) {
var d = []; //2d matrix
// Step 1
var n = s.length;
var m = t.length;
if (n == 0) return m;
if (m == 0) return n;
//Create an array of arrays in javascript (a descending loop is quicker)
for (var i = n; i >= 0; i--) d[i] = [];
// Step 2
for (var i = n; i >= 0; i--) d[i][0] = i;
for (var j = m; j >= 0; j--) d[0][j] = j;
// Step 3
for (var i = 1; i <= n; i++) {
var s_i = s.charAt(i - 1);
// Step 4
for (var j = 1; j <= m; j++) {
//Check the jagged ld total so far
if (i == j && d[i][j] > 4) return n;
var t_j = t.charAt(j - 1);
var cost = (s_i == t_j) ? 0 : 1; // Step 5
//Calculate the minimum
var mi = d[i - 1][j] + 1;
var b = d[i][j - 1] + 1;
var c = d[i - 1][j - 1] + cost;
if (b < mi) mi = b;
if (c < mi) mi = c;
d[i][j] = mi; // Step 6
//Damerau transposition
if (i > 1 && j > 1 && s_i == t.charAt(j - 2) && s.charAt(i - 2) == t_j) {
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost);
}
}
}
// Step 7
return d[n][m];
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<input type="button" id="compare" value="Compare" /><br><br>
<input type="text" id="old" class="compare" value="Alec" />
<input type="text" id="new" class="compare" value="Alexander" />
<br>
<br>
<span id="display"></span>
Podziękowania dla Jamesa Westgate za funkcję: