using System.Collections; using System.Collections.Generic; using System.Diagnostics; namespace m3uTool { public class LongestCommonSubstrings { //def longest_common_substrings(S, T): // maks = 0 # length of longest match // ret = Set([""]) # the longest matches we have found // last = {} # length of matches ending at S[i-1] and // next = {} # at S[i] for T[0]...T[n-1] // for i in xrange(len(S)): // for j in xrange(len(T)): // if S[i] == T[j]: // if j-1 in last: // next[j] = last[j-1] + 1 // else: // next[j] = 1 // if next[j] > maks: // maks = next[j] // ret = Set() // if next[j] == maks: // ret.add(S[i-maks+1:i+1]) # equals T[j-maks+1:j+1] // last = next // next = {} // return ret public static List GetLongestSubstring(string s, string t) { int maks = 0; var ret = new List(); var last = new Dictionary(); var next = new Dictionary(); for (int i = 0; i < s.Length; i++) { for (int j = 0; j < t.Length; j++) { if (s[i] == t[j]) { if (last.ContainsKey(j - 1)) next[j] = last[j - 1] + 1; else next[j] = 1; if (next[j] > maks) { maks = next[j]; ret.Clear(); } if (next[j] == maks) ret.Add(s.Substring(i - maks + 1, maks)); } } last = next; next = new Dictionary(); } return ret; } } public class LongestCommonSequence where T : IEnumerable { #region BackTracking enum public enum BackTracking { NEITHER, UP, LEFT, UP_AND_LEFT } #endregion private static int ConsecutiveMeasure(int k) { //f(k)=k*a - b; return k*k; } //public T DoLCS(T list1, T list2) //{ //} private object[] LCS(object[] list1, object[] list2) { int m = list1.Length; int n = list2.Length; var lcs = new int[m + 1,n + 1]; var backTracer = new BackTracking[m + 1,n + 1]; var w = new int[m + 1,n + 1]; int i, j; for (i = 0; i <= m; i++) { lcs[i, 0] = 0; backTracer[i, 0] = BackTracking.UP; } for (j = 0; j <= n; j++) { lcs[0, j] = 0; backTracer[0, j] = BackTracking.LEFT; } for (i = 1; i <= m; i++) { for (j = 1; j <= n; j++) { if (list1[i - 1] == list2[j - 1]) { int k = w[i - 1, j - 1]; //lcs[i,j] = lcs[i-1,j-1] + 1; lcs[i, j] = lcs[i - 1, j - 1] + ConsecutiveMeasure(k + 1) - ConsecutiveMeasure(k); backTracer[i, j] = BackTracking.UP_AND_LEFT; w[i, j] = k + 1; } else { lcs[i, j] = lcs[i - 1, j - 1]; backTracer[i, j] = BackTracking.NEITHER; } if (lcs[i - 1, j] >= lcs[i, j]) { lcs[i, j] = lcs[i - 1, j]; backTracer[i, j] = BackTracking.UP; w[i, j] = 0; } if (lcs[i, j - 1] >= lcs[i, j]) { lcs[i, j] = lcs[i, j - 1]; backTracer[i, j] = BackTracking.LEFT; w[i, j] = 0; } } } i = m; j = n; var subseq = new Stack(); // int p=lcs[i,j]; //trace the backtracking matrix. while (i > 0 || j > 0) { if (backTracer[i, j] == BackTracking.UP_AND_LEFT) { i--; j--; subseq.Push(list1[i]); // subseq = list1[i] + subseq; Trace.WriteLine(i + " " + list1[i] + " " + j); } else if (backTracer[i, j] == BackTracking.UP) { i--; } else if (backTracer[i, j] == BackTracking.LEFT) { j--; } } return subseq.ToArray(); } } }