using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; 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; List ret = new List(); Dictionary last = new Dictionary(); Dictionary 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 { public enum BackTracking { NEITHER, UP, LEFT, UP_AND_LEFT } 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 ; int[,] lcs=new int[m+1, n+1]; BackTracking[ , ] backTracer=new BackTracking[m+1, n+1]; int[,] 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; Stack 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(); } } }