@@ -260,72 +260,95 @@ template <typename _RandomAccessSequenceTy,
260
260
typename _Equivalent = std::equal_to<>>
261
261
class Diff {
262
262
typedef std::list<typename _RandomAccessSequenceTy::ElemTy> LCSList;
263
+ typedef std::list<unsigned > IndexList;
263
264
264
265
// The Longest Common Subsequence for the two sequences
265
266
LCSList _LCS;
267
+ IndexList _OrigLCSIndices;
268
+ IndexList _NewLCSIndices;
266
269
267
270
// Eat up common elements at the beginning of both sequences
268
271
inline void eatPrefix (_RandomAccessSequenceTy &Orig,
269
- _RandomAccessSequenceTy &New,
270
- LCSList &prefix) {
272
+ _RandomAccessSequenceTy &New,
273
+ IndexList &origPrefix,
274
+ IndexList &newPrefix,
275
+ unsigned origOffset,
276
+ unsigned newOffset) {
271
277
272
278
_Equivalent cmp;
273
279
while ((Orig.size () != 0 && New.size () != 0 ) &&
274
280
cmp (*Orig.begin (), *New.begin ())) {
275
281
276
282
debugOut << " Added " << *Orig.begin () <<" \n " ;
277
283
// Append the common element to the LCS
278
- prefix.push_back (New.pop_front ());
284
+ origPrefix.push_back (origOffset);
285
+ newPrefix.push_back (newOffset);
286
+ origOffset++;
287
+ newOffset++;
279
288
// Remove it from both sequences
280
289
Orig.pop_front ();
281
-
290
+ New. pop_front ();
282
291
}
283
292
}
284
293
285
294
// Eat up common elements at the end of both sequences
286
295
inline void eatSuffix (_RandomAccessSequenceTy &Orig,
287
296
_RandomAccessSequenceTy &New,
288
- LCSList &suffix) {
297
+ IndexList &origSuffix,
298
+ IndexList &newSuffix,
299
+ unsigned origOffset,
300
+ unsigned newOffset) {
289
301
290
302
_Equivalent cmp;
291
303
while ((Orig.size () != 0 && New.size () != 0 ) &&
292
304
cmp (*(Orig.end ()-1 ), *(New.end ()-1 ))) {
293
305
294
306
debugOut << " Added " << *(Orig.end ()-1 )<< " \n " ;
295
307
// Append the common element to the LCS
296
- suffix.push_front (New.pop_back ());
308
+ origSuffix.push_front (origOffset + Orig.size () - 1 );
309
+ newSuffix.push_front (newOffset + New.size () - 1 );
297
310
// Remove it from both sequences
298
311
Orig.pop_back ();
299
-
312
+ New. pop_back ();
300
313
}
301
314
}
302
315
303
316
void do_diff (_RandomAccessSequenceTy Orig,
304
317
_RandomAccessSequenceTy New,
305
- LCSList &LCS) {
318
+ IndexList &OrigLCSIndices,
319
+ IndexList &NewLCSIndices,
320
+ unsigned origOffset,
321
+ unsigned newOffset) {
306
322
307
323
debugOut << " do_diff Orig.size=" << Orig.size ()
308
324
<< " New.size=" << New.size () << std::endl;
309
325
310
326
dprintMatrix (Orig, New);
311
327
312
- LCSList prefix, suffix ;
328
+ IndexList origPrefix, origSuffix, newPrefix, newSuffix ;
313
329
// Eat up common elements at the beginning and end of the sequence
314
- eatPrefix (Orig, New, prefix);
315
- eatSuffix (Orig, New, suffix);
330
+ eatPrefix (Orig, New, origPrefix, newPrefix, origOffset, newOffset);
331
+ origOffset += origPrefix.size ();
332
+ newOffset += newPrefix.size ();
333
+ eatSuffix (Orig, New, origSuffix, newSuffix, origOffset, newOffset);
316
334
317
335
// If the problem is trivial, solve it
318
336
if (Orig.size () == 0 || New.size () == 0 ){
319
- // lcs is empty do nothing
337
+ // lcs is empty; do nothing
320
338
}
321
- else if (Orig.size () == 1 ){
322
- if (New.template contains <_Equivalent>(Orig[0 ]))
323
- LCS.push_front (Orig[0 ]);
339
+ else if (Orig.size () == 1 ) {
340
+ auto iter = New.template find <_Equivalent>(Orig[0 ]);
341
+ if (iter != New.end ()) {
342
+ OrigLCSIndices.push_front (origOffset);
343
+ NewLCSIndices.push_front (newOffset + (iter - New.begin ()));
344
+ }
324
345
}
325
- else if (New.size () == 1 ) {
326
- if (Orig.template contains <_Equivalent>(New[0 ]))
327
- LCS.push_front (New[0 ]);
328
-
346
+ else if (New.size () == 1 ) {
347
+ auto iter = Orig.template find <_Equivalent>(New[0 ]);
348
+ if (iter != Orig.end ()) {
349
+ OrigLCSIndices.push_front (origOffset + (iter - Orig.begin ()));
350
+ NewLCSIndices.push_front (newOffset);
351
+ }
329
352
// Otherwise find the bisection point, and compute the diff of the left and right part
330
353
} else {
331
354
_RandomAccessSequenceTy origLeft, origRight, newLeft, newRight;
@@ -336,19 +359,29 @@ class Diff {
336
359
New.split (bisection.x , newLeft, newRight);
337
360
338
361
// Compute the diffs of the left and right part
339
- LCSList left, right;
340
- do_diff (origLeft, newLeft, left);
341
- do_diff (origRight, newRight, right);
362
+ IndexList newLeftIndices, origLeftIndices, newRightIndices,
363
+ origRightIndices;
364
+ do_diff (origLeft, newLeft, origLeftIndices, newLeftIndices, origOffset,
365
+ newOffset);
366
+ do_diff (origRight, newRight, origRightIndices, newRightIndices,
367
+ origOffset + bisection.y , newOffset + bisection.x );
342
368
343
369
// Join the results
344
- LCS.splice (LCS.begin (), right);
345
- LCS.splice (LCS.begin (), left);
346
-
370
+ OrigLCSIndices.splice (OrigLCSIndices.begin (), origRightIndices);
371
+ OrigLCSIndices.splice (OrigLCSIndices.begin (), origLeftIndices);
372
+ NewLCSIndices.splice (NewLCSIndices.begin (), newRightIndices);
373
+ NewLCSIndices.splice (NewLCSIndices.begin (), newLeftIndices);
347
374
}
348
375
349
376
// Add the prefix and suffix back;
350
- if (!prefix.empty ()) LCS.splice (LCS.begin (), prefix);
351
- if (!suffix.empty ()) LCS.splice (LCS.end (), suffix);
377
+ if (!origPrefix.empty ()) {
378
+ OrigLCSIndices.splice (OrigLCSIndices.begin (), origPrefix);
379
+ NewLCSIndices.splice (NewLCSIndices.begin (), newPrefix);
380
+ }
381
+ if (!origSuffix.empty ()) {
382
+ OrigLCSIndices.splice (OrigLCSIndices.end (), origSuffix);
383
+ NewLCSIndices.splice (NewLCSIndices.end (), newSuffix);
384
+ }
352
385
}
353
386
354
387
Position bisect ( _RandomAccessSequenceTy Orig,
@@ -381,12 +414,17 @@ class Diff {
381
414
Diff (_RandomAccessSequenceTy Orig,
382
415
_RandomAccessSequenceTy New)
383
416
{
384
- do_diff (Orig, New, _LCS);
417
+ do_diff (Orig, New, _OrigLCSIndices, _NewLCSIndices, 0 , 0 );
418
+ // Doesn't matter which one we populate _LCS from.
419
+ for (unsigned index : _OrigLCSIndices) {
420
+ _LCS.push_back (Orig[index]);
421
+ }
385
422
}
386
423
387
- inline LCSList & LCS () {
388
- return _LCS;
389
- }
424
+ inline const LCSList & LCS () { return _LCS; }
425
+ inline const LCSList & OrigLCSIndices () { return _OrigLCSIndices; }
426
+ inline const LCSList & NewLCSIndices () { return _NewLCSIndices; }
427
+
390
428
};
391
429
392
430
0 commit comments