Created
February 1, 2019 09:05
-
-
Save tkokof/9ef00554c6c4e2338355e2d5cc531454 to your computer and use it in GitHub Desktop.
Longest Common Subsequence
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
using System.Collections.Generic; | |
public static class LCS | |
{ | |
struct LCSInfo | |
{ | |
public int Len; | |
public int BackType; | |
public LCSInfo(int l, int bt) | |
{ | |
Len = l; | |
BackType = bt; | |
} | |
} | |
static Dictionary<ulong, LCSInfo> s_lcsBuffer = new Dictionary<ulong, LCSInfo>(); | |
static StringBuilder s_lcsBuilder = new StringBuilder(4096); | |
static ulong GenBufferKey(int v1, int v2) | |
{ | |
ulong v1l = (ulong)v1; | |
ulong v2l = (ulong)v2; | |
return (v1l << 32) | v2l; | |
} | |
static void GetLCS(string str1, string str2, int length1, int length2) | |
{ | |
if (length1 >= 1 && length2 >= 1) | |
{ | |
var key = GenBufferKey(length1, length2); | |
if (s_lcsBuffer.ContainsKey(key)) | |
{ | |
var info = s_lcsBuffer[key]; | |
if (info.BackType == 1) | |
{ | |
s_lcsBuilder.Insert(0, str1[length1 - 1]); | |
GetLCS(str1, str2, length1 - 1, length2 - 1); | |
} | |
else if (info.BackType == 2) | |
{ | |
GetLCS(str1, str2, length1 - 1, length2); | |
} | |
else if (info.BackType == 3) | |
{ | |
GetLCS(str1, str2, length1, length2 - 1); | |
} | |
} | |
} | |
} | |
public static string CalcLCS(string s1, string s2) | |
{ | |
if (String.IsNullOrEmpty(s1) || String.IsNullOrEmpty(s2)) | |
{ | |
return null; | |
} | |
s_lcsBuffer.Clear(); | |
s_lcsBuilder.Length = 0; | |
for (int i = 0; i <= s1.Length; ++i) | |
{ | |
s_lcsBuffer[GenBufferKey(i, 0)] = new LCSInfo(); | |
} | |
for (int j = 0; j <= s2.Length; ++j) | |
{ | |
s_lcsBuffer[GenBufferKey(0, j)] = new LCSInfo(); | |
} | |
for (int i = 1; i <= s1.Length; ++i) | |
{ | |
for (int j = 1; j <= s2.Length; ++j) | |
{ | |
if (s1[i - 1] == s2[j - 1]) | |
{ | |
var last = s_lcsBuffer[GenBufferKey(i - 1, j - 1)]; | |
s_lcsBuffer[GenBufferKey(i, j)] = new LCSInfo(last.Len + 1, 1); | |
} | |
else | |
{ | |
var pending1 = s_lcsBuffer[GenBufferKey(i - 1, j)]; | |
var pending2 = s_lcsBuffer[GenBufferKey(i, j - 1)]; | |
if (pending1.Len > pending2.Len) | |
{ | |
s_lcsBuffer[GenBufferKey(i, j)] = new LCSInfo(pending1.Len, 2); | |
} | |
else | |
{ | |
s_lcsBuffer[GenBufferKey(i, j)] = new LCSInfo(pending2.Len, 3); | |
} | |
} | |
} | |
} | |
GetLCS(s1, s2, s1.Length, s2.Length); | |
return s_lcsBuilder.ToString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment