Sử dụng JavaScript để chấm điểm phản hồi của người dùng (so sánh hai mảng)
Tôi đang làm việc trên một kịch bản để chấm điểm phản hồi của người dùng bằng cách so sánh hai mảng. (Đây là một bài kiểm tra để xem họ biết thông tin theo từng từ chính xác đến mức nào.) Tôi đã có một số mã mà tôi cần, như chuyển phản hồi của người dùng thành chữ thường và tách nó. Tất cả những gì tôi cần là một thứ gì đó để tìm số khác biệt/ lỗi. Ví dụ:
var correctanswer = ["The","quick","brown","fox","jumped","over","the","lazy","dog"];
var useranswer = ["The","brown","fox","jumped","up","and","over","the","really","lazy","cat"];
alert(counterrors(correctanswer, useranswer));
Trong ví dụ cụ thể này, chạy hàm mà tôi đang tìm kiếm sẽ trả về rằng người dùng đã mắc 5 lỗi (họ bỏ qua "quick", thêm "up", "and", và "really", và thay đổi "dog" thành "cat"). Như bạn có thể thấy, hai mảng có thể có độ dài khác nhau.
Có ai biết cách tiếp cận việc này không? Tôi đang nghĩ nó có lẽ sẽ là một vòng lặp như:
for (x in correctanswer) {
// compare correctanswer[x] to useranswer[x]... not sure how exactly. Seems tricky...
}
Cảm ơn bạn đã xem qua điều này! Tôi đã xem giải pháp diff của John Resig (http://ejohn.org/projects/javascript-diff-algorithm/) và những thứ tương tự khác, thậm chí một vài so sánh mảng, nhưng không cái nào hoạt động vì những cái tôi tìm thấy trả về tất cả các khác biệt, trong khi tôi muốn biết có bao nhiêu khác biệt. Một lần nữa, cảm ơn bạn đã xem và xin vui lòng cho tôi biết nếu có bất kỳ câu hỏi nào.
Cập nhật: Cảm ơn rất nhiều Magnar về câu trả lời! Nó đã hoạt động hoàn hảo.
Câu trả lời #1
Điều bạn đang tìm là Khoảng cách Levenshtein của hai mảng.
Đây là một thuật toán tính toán số lượng cộng, xóa và thay thế cần thiết để biến đổi một chuỗi thành chuỗi khác.
Trang Wikipedia mà tôi liên kết có một triển khai bằng giả mã. Tôi đã dịch từng dòng sang JavaScript cho bạn:
var correctanswer = ["The","quick","brown","fox","jumped","over","the","lazy","dog"];
var useranswer = ["The","brown","fox","jumped","up","and","over","the","really","lazy","cat"];
console.log(calculate_levenshtein_distance(correctanswer, useranswer));
function calculate_levenshtein_distance(s, t) {
var m = s.length + 1, n = t.length + 1;
var i, j;
// for all i and j, d[i,j] will hold the Levenshtein distance between
// the first i words of s and the first j words of t;
// note that d has (m+1)x(n+1) values
var d = [];
for (i = 0; i < m; i++) {
d[i] = [i]; // the distance of any first array to an empty second array
}
for (j = 0; j < n; j++) {
d[0][j] = j; // the distance of any second array to an empty first array
}
for (j = 1; j < n; j++) {
for (i = 1; i < m; i++) {
if (s[i - 1] === t[j - 1]) {
d[i][j] = d[i-1][j-1]; // no operation required
} else {
d[i][j] = Math.min(
d[i - 1][j] + 1, // a deletion
d[i][j - 1] + 1, // an insertion
d[i - 1][j - 1] + 1 // a substitution
);
}
}
}
return d[m - 1][n - 1];
}
Điều này sẽ ghi 5 vào console. Như bạn sẽ thấy, đây là khoảng cách đúng giữa các mảng. Học sinh đã không thêm lazy. Vì vậy, có 1 xóa, 3 thêm và 1 thay thế.
Câu trả lời số 2
Tôi không chắc mình có hoàn toàn hiểu những gì bạn muốn nhưng tôi nghĩ đây là giải pháp.
function counterrors(a, b) {
var max = Math.max(a.length, b.length);
var min = Math.min(a.length, b.length);
var count = 0;
for (var i = 0; i < min; i+=1) {
if (a[i] !== b[i]) {
count += 1;
}
}
return count + max - min; // max - min for any extra things that don't match
}
var correctanswer = ["The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];
var useranswer = ["The", "brown", "fox", "jumped", "up", "and", "over", "the", "really", "lazy", "cat"];
alert(counterrors(correctanswer, useranswer));
