migrated LCS implementation, still experimenting...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2021-06-17 20:06:16 +03:00
parent 50b381600d
commit 4cc6f8984b
2 changed files with 121 additions and 2 deletions

View File

@ -224,8 +224,10 @@ var getDiffSections = function(A, B, cmp, min_chunk){
// store the gap... // store the gap...
;(a != e.A || b != e.B) ;(a != e.A || b != e.B)
&& gaps.push([ && gaps.push([
[a, A.slice(a, e.A)], [a,
[b, B.slice(b, e.B)], A.slice(a, e.A)],
[b,
B.slice(b, e.B)],
]) ])
// go to next gap... // go to next gap...
a = e.A + e.length a = e.A + e.length

117
diff2.js
View File

@ -33,6 +33,36 @@ var types = require('ig-types')
// - reconstruct protocol // - reconstruct protocol
// //
// //
// XXX proposed diff format:
// [
// // change...
// [
// // pre-context...
// // XXX should '=' here be optional???
// ['=', <path>, <value>],
// ...
// ['=', <path>, <value>],
//
// // changes...
// // addition...
// ['+', <path>, <value>],
// // removal...
// ['-', <path>, <value>],
// // unchanged context line....
// ['=', <path>, <value>],
// ...
//
// // post-context...
// ['=', <path>, <value>],
// ...
// ['=', <path>, <value>],
// ],
//
// ...
// ]
//
//
//
/*********************************************************************/ /*********************************************************************/
var STOP = var STOP =
@ -601,6 +631,83 @@ function(root, spec){
//---------------------------------------------------------------------
// Get common chunks (LCS)...
//
// Format:
// [
// <total-intersection-length>,
//
// // XXX should this be an obj???
// [
// <offset-A>,
// <offset-B>,
// <section-length>,
// ],
// ...
// ]
//
var commonSections =
module.commonSections =
function(A, B, cmp){
cmp = cmp
|| function(a, b){
return a === b || a == b }
var LCS = function(a, b){
// calculate length of chunk...
var l = 0
while(a+l < A.length && b+l < B.length
&& a+l in A && b+l in B
&& cmp(A[a+l], B[b+l])){
l++ }
// get next chunks...
var L = A.length > a+l ?
LCS(a+l+1, b+l)
: [0]
var R = B.length > b+l ?
LCS(a+l, b+l+1)
: [0]
// select the best chunk-set...
// NOTE: we maximize the number of elements in a chunk set then
// minimize the number of chunks per set...
var next = L[0] == R[0] ?
(L.length < R.length ? L : R)
: L[0] > R[0] ?
L
: R
return (
// non-empty chunk and next...
next[0] > 0 && l > 0 ?
[l + next[0], [a, b, l]].concat(next.slice(1))
// non-empty chunk and empty next...
: l > 0 ?
[l, [a, b, l]]
// empty chunk...
: next ) }
return LCS(0, 0) }
var diffSections =
function(A, B, cmp){
var pa = 0
var pb = 0
return commonSections(A, B, cmp)
.slice(1)
.concat([[A.length, B.length, 0]])
.reduce(function(gaps, [a, b, l]){
;(pa == a && pb == b)
|| gaps.push([
pa,
A.slice(pa, a),
pb,
B.slice(pb, b),
])
pa = a + l
pb = b + l
return gaps }, []) }
@ -701,6 +808,16 @@ console.log('\n\n---\n',
)]) )])
var A = [1,2,3,1,2,3,4,5,,,4]
var B = [1,2,3,4,5,6]
console.log(A)
console.log(B)
console.log(
commonSections(A, B))
console.log(
diffSections(A, B))
/********************************************************************** /**********************************************************************
* vim:set ts=4 sw=4 : */ return module }) * vim:set ts=4 sw=4 : */ return module })