Elv*_* S. 12 javascript string algorithm difference
我需要找到两个字符串之间的差异。
const string1 = 'lebronjames';
const string2 = 'lebronnjames';
Run Code Online (Sandbox Code Playgroud)
预期的输出是找到额外的n并将其记录到控制台。
有没有办法在 JavaScript 中做到这一点?
Tre*_*ium 17
对于更复杂的差异检查,另一种选择是使用 PatienceDiff 算法。我将此算法移植到 Javascript 中...
https://github.com/jonTrent/PatienceDiff
...尽管该算法通常用于文本的逐行比较(例如计算机程序),但它仍然可以用于逐字符的比较。例如,要比较两个字符串,您可以执行以下操作......
let a = "thelebronnjamist";
let b = "the lebron james";
let difference = patienceDiff( a.split(""), b.split("") );
Run Code Online (Sandbox Code Playgroud)
...将difference.lines比较结果设置为数组...
difference.lines: Array(19)
0: {line: "t", aIndex: 0, bIndex: 0}
1: {line: "h", aIndex: 1, bIndex: 1}
2: {line: "e", aIndex: 2, bIndex: 2}
3: {line: " ", aIndex: -1, bIndex: 3}
4: {line: "l", aIndex: 3, bIndex: 4}
5: {line: "e", aIndex: 4, bIndex: 5}
6: {line: "b", aIndex: 5, bIndex: 6}
7: {line: "r", aIndex: 6, bIndex: 7}
8: {line: "o", aIndex: 7, bIndex: 8}
9: {line: "n", aIndex: 8, bIndex: 9}
10: {line: "n", aIndex: 9, bIndex: -1}
11: {line: " ", aIndex: -1, bIndex: 10}
12: {line: "j", aIndex: 10, bIndex: 11}
13: {line: "a", aIndex: 11, bIndex: 12}
14: {line: "m", aIndex: 12, bIndex: 13}
15: {line: "i", aIndex: 13, bIndex: -1}
16: {line: "e", aIndex: -1, bIndex: 14}
17: {line: "s", aIndex: 14, bIndex: 15}
18: {line: "t", aIndex: 15, bIndex: -1}
Run Code Online (Sandbox Code Playgroud)
其中aIndex === -1orbIndex === -1表示两个字符串之间的差异。具体来说...
b位置 3 中找到了字符“ ”。a位置 9 中找到了字符“n”。b位置 10 中找到了字符“ ”。a位置 13 中找到了字符“i”。b位置 14 中找到了字符“e”。a位置 15 中找到了字符“t”。请注意,PatienceDiff 算法对于比较两个相似的文本或字符串块非常有用。它不会告诉您是否发生了基本编辑。例如,以下...
let a = "james lebron";
let b = "lebron james";
let difference = patienceDiff( a.split(""), b.split("") );
Run Code Online (Sandbox Code Playgroud)
...返回difference.lines包含...
difference.lines: Array(18)
0: {line: "j", aIndex: 0, bIndex: -1}
1: {line: "a", aIndex: 1, bIndex: -1}
2: {line: "m", aIndex: 2, bIndex: -1}
3: {line: "e", aIndex: 3, bIndex: -1}
4: {line: "s", aIndex: 4, bIndex: -1}
5: {line: " ", aIndex: 5, bIndex: -1}
6: {line: "l", aIndex: 6, bIndex: 0}
7: {line: "e", aIndex: 7, bIndex: 1}
8: {line: "b", aIndex: 8, bIndex: 2}
9: {line: "r", aIndex: 9, bIndex: 3}
10: {line: "o", aIndex: 10, bIndex: 4}
11: {line: "n", aIndex: 11, bIndex: 5}
12: {line: " ", aIndex: -1, bIndex: 6}
13: {line: "j", aIndex: -1, bIndex: 7}
14: {line: "a", aIndex: -1, bIndex: 8}
15: {line: "m", aIndex: -1, bIndex: 9}
16: {line: "e", aIndex: -1, bIndex: 10}
17: {line: "s", aIndex: -1, bIndex: 11}
Run Code Online (Sandbox Code Playgroud)
请注意,PatienceDiff 不会报告名字和姓氏的交换,而是提供一个结果,显示从中删除了哪些字符a以及添加了哪些字符b以最终得到 的结果b。
编辑:添加了名为PatientDiffPlus的新算法。
在仔细考虑了上面提供的最后一个示例后,我发现 PatienceDiff 在识别可能移动的线条方面存在局限性,我突然意识到有一种优雅的方法可以使用 PatienceDiff 算法来确定是否有任何线条确实可能移动,而不仅仅是显示删除和添加。
简而言之,我将patienceDiffPlus算法(添加到上面标识的 GitHub 存储库中)添加到 PatienceDiff.js 文件的底部。该patienceDiffPlus算法从初始patienceDiff算法中获取删除的 aLines[] 和添加的 bLines[],并再次运行该patienceDiff算法。即,patienceDiffPlus正在寻找可能移动的线的最长公共子序列,然后将其记录在原始patienceDiff结果中。该patienceDiffPlus算法继续此操作,直到找不到更多移动的线。
现在,使用patienceDiffPlus,进行以下比较...
let a = "james lebron";
let b = "lebron james";
let difference = patienceDiffPlus( a.split(""), b.split("") );
Run Code Online (Sandbox Code Playgroud)
...返回difference.lines包含...
difference.lines: Array(18)
0: {line: "j", aIndex: 0, bIndex: -1, moved: true}
1: {line: "a", aIndex: 1, bIndex: -1, moved: true}
2: {line: "m", aIndex: 2, bIndex: -1, moved: true}
3: {line: "e", aIndex: 3, bIndex: -1, moved: true}
4: {line: "s", aIndex: 4, bIndex: -1, moved: true}
5: {line: " ", aIndex: 5, bIndex: -1, moved: true}
6: {line: "l", aIndex: 6, bIndex: 0}
7: {line: "e", aIndex: 7, bIndex: 1}
8: {line: "b", aIndex: 8, bIndex: 2}
9: {line: "r", aIndex: 9, bIndex: 3}
10: {line: "o", aIndex: 10, bIndex: 4}
11: {line: "n", aIndex: 11, bIndex: 5}
12: {line: " ", aIndex: 5, bIndex: 6, moved: true}
13: {line: "j", aIndex: 0, bIndex: 7, moved: true}
14: {line: "a", aIndex: 1, bIndex: 8, moved: true}
15: {line: "m", aIndex: 2, bIndex: 9, moved: true}
16: {line: "e", aIndex: 3, bIndex: 10, moved: true}
17: {line: "s", aIndex: 4, bIndex: 11, moved: true}
Run Code Online (Sandbox Code Playgroud)
请注意添加的属性moved,该属性标识行(或本例中的字符)是否可能被移动。同样,patienceDiffPlus只是匹配删除的 aLines[] 和添加的 bLines[],因此不能保证这些行确实被移动,但很有可能它们确实被移动。
G.a*_*ziz 11
这将返回两个字符串之间的第一个差异
喜欢 lebronjames和lebronnjames是n
const string1 = 'lebronjames';
const string2 = 'lebronnjabes';
const findFirstDiff = (str1, str2) =>
str2[[...str1].findIndex((el, index) => el !== str2[index])];
// equivalent of
const findFirstDiff2 = function(str1, str2) {
return str2[[...str1].findIndex(function(el, index) {
return el !== str2[index]
})];
}
console.log(findFirstDiff2(string1, string2));
console.log(findFirstDiff(string1, string2));Run Code Online (Sandbox Code Playgroud)
小智 5
function getDifference(a, b)
{
var i = 0;
var j = 0;
var result = "";
while (j < b.length)
{
if (a[i] != b[j] || i == a.length)
result += b[j];
else
i++;
j++;
}
return result;
}
console.log(getDifference("lebronjames", "lebronnjames"));Run Code Online (Sandbox Code Playgroud)
对于那些想要返回两个字符串之间的第一个差异的人可以这样调整:
const getDifference = (s, t) => {
s = [...s].sort();
t = [...t].sort();
return t.find((char, i) => char !== s[i]);
};
console.log(getDifference('lebronjames', 'lebronnjames'));
console.log(getDifference('abc', 'abcd'));Run Code Online (Sandbox Code Playgroud)
const getDifference = (s, t) => {
let sum = t.charCodeAt(t.length - 1);
for (let j = 0; j < s.length; j++) {
sum -= s.charCodeAt(j);
sum += t.charCodeAt(j);
}
return String.fromCharCode(sum);
};
console.log(getDifference('lebronjames', 'lebronnjames'));
console.log(getDifference('abc', 'abcd'));Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19571 次 |
| 最近记录: |