4 using System.Collections.Generic;
7 namespace SiliconStudio.Quantum
14 public static class LCS
16 public static int[,] GetLCS<T>(
IList<T> str1,
IList<T> str2, IEqualityComparer<T> comparer = null)
21 GetLCSInternal(str1, str2, out table, comparer);
25 public static List<T> ReadLCSFromBacktrack<T>(
int[,] backtrack,
IList<T> string1,
IList<T> string2, IEqualityComparer<T> comparer = null)
29 var result =
new List<T>();
30 ReadLCSFromBacktrack(backtrack, string1, string2, string1.Count - 1, string2.Count - 1, result, comparer);
45 public int SourceIndex {
get; set; }
48 public static void ApplyDiff<T>(
IList<T> list1,
IList<T> list2, List<Diff> differences, Func<T, T> copyItem = null)
51 foreach (var difference
in differences)
53 switch (difference.Action)
59 list1.Insert(index, copyItem != null ? copyItem(list2[difference.SourceIndex]) : list2[difference.SourceIndex]);
62 case DiffAction.Remove:
63 list1.RemoveAt(index);
69 public static List<Diff> GenerateDiff<T>(
int[,] backtrack,
IList<T> list1,
IList<T> list2, IEqualityComparer<T> comparer = null)
73 var differences =
new List<Diff>();
74 GenerateDiff(backtrack, list1, list2, list1.Count - 1, list2.Count - 1, differences, comparer);
79 private static void GenerateDiff<T>(
int[,] backtrack,
IList<T> list1,
IList<T> list2,
int list1Position,
int list2Position, List<Diff> differences, IEqualityComparer<T> comparer)
81 if (list1Position >= 0 && list2Position >= 0 && comparer.Equals(list1[list1Position], list2[list2Position]))
83 GenerateDiff(backtrack, list1, list2, list1Position - 1, list2Position - 1, differences, comparer);
85 differences.Add(
new Diff { Action = DiffAction.Skip });
89 if (list2Position >= 0 && (list1Position == -1 || backtrack[list1Position + 1, list2Position] >= backtrack[list1Position, list2Position + 1]))
91 GenerateDiff(backtrack, list1, list2, list1Position, list2Position - 1, differences, comparer);
93 differences.Add(
new Diff { Action = DiffAction.Add, SourceIndex = list2Position });
95 else if (list1Position >= 0 && (list2Position == -1 || backtrack[list1Position + 1, list2Position] < backtrack[list1Position, list2Position + 1]))
97 GenerateDiff(backtrack, list1, list2, list1Position - 1, list2Position, differences, comparer);
99 differences.Add(
new Diff { Action = DiffAction.Remove });
104 private static void GetLCSInternal<T>(
IList<T> list1,
IList<T> list2, out
int[,] matrix, IEqualityComparer<T> comparer)
108 if (list1.Count == 0 || list2.Count == 0)
113 var table =
new int[list1.Count + 1, list2.Count + 1];
114 for (
int i = 0; i < table.GetLength(0); i++)
118 for (
int j = 0; j < table.GetLength(1); j++)
123 for (
int i = 1; i < table.GetLength(0); i++)
125 for (
int j = 1; j < table.GetLength(1); j++)
127 if (comparer.Equals(list1[i - 1], list2[j - 1]))
128 table[i, j] = table[i - 1, j - 1] + 1;
131 if (table[i, j - 1] > table[i - 1, j])
132 table[i, j] = table[i, j - 1];
134 table[i, j] = table[i - 1, j];
142 private static void ReadLCSFromBacktrack<T>(
int[,] backtrack,
IList<T> list1,
IList<T> list2,
int list1Position,
int list2Position,
ICollection<T> result, IEqualityComparer<T> comparer)
144 if ((list1Position < 0) || (list2Position < 0))
147 else if (comparer.Equals(list1[list1Position], list2[list2Position]))
149 ReadLCSFromBacktrack(backtrack, list1, list2, list1Position - 1, list2Position - 1, result, comparer);
150 result.Add(list1[list1Position]);
154 if (backtrack[list1Position, list2Position - 1] >= backtrack[list1Position - 1, list2Position])
156 ReadLCSFromBacktrack(backtrack, list1, list2, list1Position, list2Position - 1, result, comparer);
160 ReadLCSFromBacktrack(backtrack, list1, list2, list1Position - 1, list2Position, result, comparer);
Algorithms to solve the Longest Common Subsequence problem. http://en.wikibooks.org/wiki/Algorithm_Im...