WIP
DirectOutput framework for virtual pinball cabinets WIP
Go to:
Overview 
LongestCommonSubsequenceExtensions.cs
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * modified by Tyler Jensen from
3  * http://www.codeproject.com/KB/recipes/lcs.aspx
4  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5 
6 using System;
7 using System.Collections.Generic;
8 using System.Linq;
9 using System.Text;
10 
11 namespace FuzzyStrings
12 {
13  public static class LongestCommonSubsequenceExtensions
14  {
22  public static Tuple<string, double> LongestCommonSubsequence(this string input, string comparedTo, bool caseSensitive = false)
23  {
24  if (string.IsNullOrWhiteSpace(input) || string.IsNullOrWhiteSpace(comparedTo)) return new Tuple<string, double>(string.Empty, 0.0d);
25  if (!caseSensitive)
26  {
27  input = input.ToLower();
28  comparedTo = comparedTo.ToLower();
29  }
30 
31  int inputLen = input.Length;
32  int comparedToLen = comparedTo.Length;
33 
34  int[,] lcs = new int[inputLen + 1, comparedToLen + 1];
35  LcsDirection[,] tracks = new LcsDirection[inputLen + 1, comparedToLen + 1];
36  int[,] w = new int[inputLen + 1, comparedToLen + 1];
37  int i, j;
38 
39  for (i = 0; i <= inputLen; ++i)
40  {
41  lcs[i, 0] = 0;
42  tracks[i, 0] = LcsDirection.North;
43 
44  }
45  for (j = 0; j <= comparedToLen; ++j)
46  {
47  lcs[0, j] = 0;
48  tracks[0, j] = LcsDirection.West;
49  }
50 
51  for (i = 1; i <= inputLen; ++i)
52  {
53  for (j = 1; j <= comparedToLen; ++j)
54  {
55  if (input[i - 1].Equals(comparedTo[j - 1]))
56  {
57  int k = w[i - 1, j - 1];
58  //lcs[i,j] = lcs[i-1,j-1] + 1;
59  lcs[i, j] = lcs[i - 1, j - 1] + Square(k + 1) - Square(k);
60  tracks[i, j] = LcsDirection.NorthWest;
61  w[i, j] = k + 1;
62  }
63  else
64  {
65  lcs[i, j] = lcs[i - 1, j - 1];
66  tracks[i, j] = LcsDirection.None;
67  }
68 
69  if (lcs[i - 1, j] >= lcs[i, j])
70  {
71  lcs[i, j] = lcs[i - 1, j];
72  tracks[i, j] = LcsDirection.North;
73  w[i, j] = 0;
74  }
75 
76  if (lcs[i, j - 1] >= lcs[i, j])
77  {
78  lcs[i, j] = lcs[i, j - 1];
79  tracks[i, j] = LcsDirection.West;
80  w[i, j] = 0;
81  }
82  }
83  }
84 
85  i = inputLen;
86  j = comparedToLen;
87 
88  string subseq = "";
89  double p = lcs[i, j];
90 
91  //trace the backtracking matrix.
92  while (i > 0 || j > 0)
93  {
94  if (tracks[i, j] == LcsDirection.NorthWest)
95  {
96  i--;
97  j--;
98  subseq = input[i] + subseq;
99  //Trace.WriteLine(i + " " + input1[i] + " " + j);
100  }
101 
102  else if (tracks[i, j] == LcsDirection.North)
103  {
104  i--;
105  }
106 
107  else if (tracks[i, j] == LcsDirection.West)
108  {
109  j--;
110  }
111  }
112 
113  double coef = p / (inputLen * comparedToLen);
114 
115  Tuple<string, double> retval = new Tuple<string, double>(subseq, coef);
116  return retval;
117  }
118 
119  private static int Square(int p)
120  {
121  return p * p;
122  }
123  }
124 
125  internal enum LcsDirection
126  {
127  None,
128  North,
129  West,
130  NorthWest
131  }
132 }