Files
m3uTool/Backup/LongestCommonSequence.cs
T

176 lines
3.8 KiB
C#

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<string> GetLongestSubstring(string s, string t)
{
int maks = 0;
List<string> ret = new List<string>();
Dictionary<int, int> last = new Dictionary<int, int>();
Dictionary<int, int> next = new Dictionary<int, int>();
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<int, int>();
}
return ret;
}
}
public class LongestCommonSequence<T> 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<object> subseq = new Stack<object>();
// 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();
}
}
}