mirror of
https://github.com/danog/dart-sass.git
synced 2024-11-30 04:39:03 +01:00
Add an LCS implementation.
This commit is contained in:
parent
ab2d8ae3f3
commit
efaf64020f
@ -97,3 +97,40 @@ SimpleSelector unifyUniversalAndElement(SimpleSelector selector1,
|
||||
: new TypeSelector(
|
||||
new NamespacedIdentifier(name, namespace: namespace));
|
||||
}
|
||||
|
||||
List/*<T>*/ longestCommonSubsequence/*<T>*/(List/*<T>*/ list1,
|
||||
List/*<T>*/ list2, {/*=T*/ select(/*=T*/ element1, /*=T*/ element2)}) {
|
||||
select ??= (element1, element2) => element1 == element2 ? element1 : null;
|
||||
|
||||
var lengths = new List.generate(
|
||||
list1.length + 1, (_) => new List.filled(list2.length + 1, 0),
|
||||
growable: false);
|
||||
|
||||
var selections = new List.generate(
|
||||
list1.length, (_) => new List/*<T>*/(list2.length),
|
||||
growable: false);
|
||||
|
||||
// TODO(nweiz): Calling [select] here may be expensive. Can we use a memoizing
|
||||
// approach to avoid calling it O(n*m) times in most cases?
|
||||
for (var i = 0; i < list1.length; i++) {
|
||||
for (var j = 0; j < list2.length; j++) {
|
||||
var selection = select(list1[i], list2[j]);
|
||||
selections[i][j] = selection;
|
||||
lengths[i + 1][j + 1] = selection == null
|
||||
? math.max(lengths[i + 1][j], lengths[i][j + 1])
|
||||
: lengths[i][j] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
List/*<T>*/ backtrack(int i, int j) {
|
||||
if (i == -1 || j == -1) return [];
|
||||
var selection = selections[i][j];
|
||||
if (selection != null) return backtrack(i - 1, j - 1)..add(selection);
|
||||
|
||||
return lengths[i + 1][j] > lengths[i][j + 1]
|
||||
? backtrack(i, j - 1)
|
||||
: backtrack(i - 1, j);
|
||||
}
|
||||
|
||||
return backtrack(list1.length - 1, list2.length - 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user