2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -5,6 +5,7 @@
|
|||
#include <deque>
|
||||
#include <map>
|
||||
#include <algorithm> // for lower_bound()
|
||||
#include <iterator> // for prev()
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ protected:
|
|||
typedef deque<INDEXES*> MATCHES;
|
||||
|
||||
// return the LCS as a linked list of matched index pairs
|
||||
uint64_t LCS::Pairs(MATCHES& matches, shared_ptr<Pair> *pairs) {
|
||||
uint64_t Pairs(MATCHES& matches, shared_ptr<Pair> *pairs) {
|
||||
auto trace = pairs != nullptr;
|
||||
PAIRS traces;
|
||||
THRESHOLD threshold;
|
||||
|
|
@ -79,6 +80,7 @@ protected:
|
|||
if (limit == threshold.end()) {
|
||||
// insert case
|
||||
threshold.push_back(index2);
|
||||
limit = prev(threshold.end());
|
||||
if (trace) {
|
||||
auto prefix = index3 > 0 ? traces[index3 - 1] : nullptr;
|
||||
auto last = make_shared<Pair>(index1, index2, prefix);
|
||||
|
|
|
|||
|
|
@ -1,46 +1,36 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX(A,B) (((A)>(B))? (A) : (B))
|
||||
#define MAX(a, b) (a > b ? a : b)
|
||||
|
||||
char * lcs(const char *a,const char * b) {
|
||||
int lena = strlen(a)+1;
|
||||
int lenb = strlen(b)+1;
|
||||
|
||||
int bufrlen = 40;
|
||||
char bufr[40], *result;
|
||||
|
||||
int i,j;
|
||||
const char *x, *y;
|
||||
int *la = calloc(lena*lenb, sizeof( int));
|
||||
int **lengths = malloc( lena*sizeof( int*));
|
||||
for (i=0; i<lena; i++) lengths[i] = la + i*lenb;
|
||||
|
||||
for (i=0,x=a; *x; i++, x++) {
|
||||
for (j=0,y=b; *y; j++,y++ ) {
|
||||
if (*x == *y) {
|
||||
lengths[i+1][j+1] = lengths[i][j] +1;
|
||||
int lcs (char *a, int n, char *b, int m, char **s) {
|
||||
int i, j, k, t;
|
||||
int *z = calloc((n + 1) * (m + 1), sizeof (int));
|
||||
int **c = calloc((n + 1), sizeof (int *));
|
||||
for (i = 0; i <= n; i++) {
|
||||
c[i] = &z[i * (m + 1)];
|
||||
}
|
||||
for (i = 1; i <= n; i++) {
|
||||
for (j = 1; j <= m; j++) {
|
||||
if (a[i - 1] == b[j - 1]) {
|
||||
c[i][j] = c[i - 1][j - 1] + 1;
|
||||
}
|
||||
else {
|
||||
int ml = MAX(lengths[i+1][j], lengths[i][j+1]);
|
||||
lengths[i+1][j+1] = ml;
|
||||
c[i][j] = MAX(c[i - 1][j], c[i][j - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = bufr+bufrlen;
|
||||
*--result = '\0';
|
||||
i = lena-1; j = lenb-1;
|
||||
while ( (i>0) && (j>0) ) {
|
||||
if (lengths[i][j] == lengths[i-1][j]) i -= 1;
|
||||
else if (lengths[i][j] == lengths[i][j-1]) j-= 1;
|
||||
else {
|
||||
// assert( a[i-1] == b[j-1]);
|
||||
*--result = a[i-1];
|
||||
i-=1; j-=1;
|
||||
}
|
||||
t = c[n][m];
|
||||
*s = malloc(t);
|
||||
for (i = n, j = m, k = t - 1; k >= 0;) {
|
||||
if (a[i - 1] == b[j - 1])
|
||||
(*s)[k] = a[i - 1], i--, j--, k--;
|
||||
else if (c[i][j - 1] > c[i - 1][j])
|
||||
j--;
|
||||
else
|
||||
i--;
|
||||
}
|
||||
free(la); free(lengths);
|
||||
return strdup(result);
|
||||
free(c);
|
||||
free(z);
|
||||
return t;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
int main()
|
||||
{
|
||||
printf("%s\n", lcs("thisisatest", "testing123testing")); // tsitest
|
||||
int main () {
|
||||
char a[] = "thisisatest";
|
||||
char b[] = "testing123testing";
|
||||
int n = sizeof a - 1;
|
||||
int m = sizeof b - 1;
|
||||
char *s = NULL;
|
||||
int t = lcs(a, n, b, m, &s);
|
||||
printf("%.*s\n", t, s); // tsitest
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
defmodule LCS do
|
||||
def lcs(a, b) do
|
||||
lcs(to_charlist(a), to_charlist(b), []) |> to_string
|
||||
end
|
||||
|
||||
defp lcs([h|at], [h|bt], res), do: lcs(at, bt, [h|res])
|
||||
defp lcs([_|at]=a, [_|bt]=b, res) do
|
||||
Enum.max_by([lcs(a, bt, res), lcs(at, b, res)], &length/1)
|
||||
end
|
||||
defp lcs(_, _, res), do: res |> Enum.reverse
|
||||
end
|
||||
|
||||
IO.puts LCS.lcs("thisisatest", "testing123testing")
|
||||
IO.puts LCS.lcs('1234','1224533324')
|
||||
|
|
@ -1,36 +1,34 @@
|
|||
defmodule LCS do
|
||||
def lcs_length(s,t) do
|
||||
{l,_c} = lcs_length(s,t,Map.new)
|
||||
l
|
||||
end
|
||||
def lcs_length(s,t), do: lcs_length(s,t,Map.new) |> elem(0)
|
||||
|
||||
defp lcs_length([],t,cache), do: {0,Dict.put(cache,{[],t},0)}
|
||||
defp lcs_length(s,[],cache), do: {0,Dict.put(cache,{s,[]},0)}
|
||||
defp lcs_length([],t,cache), do: {0,Map.put(cache,{[],t},0)}
|
||||
defp lcs_length(s,[],cache), do: {0,Map.put(cache,{s,[]},0)}
|
||||
defp lcs_length([h|st]=s,[h|tt]=t,cache) do
|
||||
{l,c} = lcs_length(st,tt,cache)
|
||||
{l+1,Dict.put(c,{s,t},l+1)}
|
||||
{l+1,Map.put(c,{s,t},l+1)}
|
||||
end
|
||||
defp lcs_length([_sh|st]=s,[_th|tt]=t,cache) do
|
||||
if Dict.has_key?(cache,{s,t}) do
|
||||
{Dict.get(cache,{s,t}),cache}
|
||||
if Map.has_key?(cache,{s,t}) do
|
||||
{Map.get(cache,{s,t}),cache}
|
||||
else
|
||||
{l1,c1} = lcs_length(s,tt,cache)
|
||||
{l2,c2} = lcs_length(st,t,c1)
|
||||
l = Enum.max([l1,l2])
|
||||
{l,Dict.put(c2,{s,t},l)}
|
||||
l = max(l1,l2)
|
||||
{l,Map.put(c2,{s,t},l)}
|
||||
end
|
||||
end
|
||||
|
||||
def lcs(s,t) do
|
||||
{s,t} = {to_charlist(s),to_charlist(t)}
|
||||
{_,c} = lcs_length(s,t,Map.new)
|
||||
lcs(s,t,c,[])
|
||||
lcs(s,t,c,[]) |> to_string
|
||||
end
|
||||
|
||||
defp lcs([],_,_,acc), do: Enum.reverse(acc)
|
||||
defp lcs(_,[],_,acc), do: Enum.reverse(acc)
|
||||
defp lcs([h|st],[h|tt],cache,acc), do: lcs(st,tt,cache,[h|acc])
|
||||
defp lcs([_sh|st]=s,[_th|tt]=t,cache,acc) do
|
||||
if Dict.get(cache,{s,tt}) > Dict.get(cache,{st,t}) do
|
||||
if Map.get(cache,{s,tt}) > Map.get(cache,{st,t}) do
|
||||
lcs(s,tt,cache,acc)
|
||||
else
|
||||
lcs(st,t,cache,acc)
|
||||
|
|
@ -38,5 +36,5 @@ defmodule LCS do
|
|||
end
|
||||
end
|
||||
|
||||
IO.puts LCS.lcs('thisisatest','testing123testing')
|
||||
IO.puts LCS.lcs('1234','1224533324')
|
||||
IO.puts LCS.lcs("thisisatest","testing123testing")
|
||||
IO.puts LCS.lcs("1234","1224533324")
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
sub lcs(Str $xstr, Str $ystr) {
|
||||
my ($a,$b) = ([$xstr.comb],[$ystr.comb]);
|
||||
|
||||
my $positions;
|
||||
for $a.kv -> $i,$x { $positions{$x} +|= 1 +< $i };
|
||||
|
||||
my $S = +^0;
|
||||
my $Vs = [];
|
||||
my ($y,$u);
|
||||
for (0..+$b-1) -> $j {
|
||||
$y = $positions{$b[$j]} // 0;
|
||||
$u = $S +& $y;
|
||||
$S = ($S + $u) +| ($S - $u);
|
||||
$Vs[$j] = $S;
|
||||
}
|
||||
|
||||
my ($i,$j) = (+$a-1, +$b-1);
|
||||
my $result = "";
|
||||
while ($i >= 0 && $j >= 0) {
|
||||
if ($Vs[$j] +& (1 +< $i)) { $i-- }
|
||||
else {
|
||||
unless ($j && +^$Vs[$j-1] +& (1 +< $i)) {
|
||||
$result = $a[$i] ~ $result;
|
||||
$i--;
|
||||
}
|
||||
$j--;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
say lcs("thisisatest", "testing123testing");
|
||||
|
|
@ -1,6 +1,14 @@
|
|||
use Algorithm::Diff qw/ LCS /;
|
||||
sub lcs {
|
||||
my ($a, $b) = @_;
|
||||
if (!length($a) || !length($b)) {
|
||||
return "";
|
||||
}
|
||||
if (substr($a, 0, 1) eq substr($b, 0, 1)) {
|
||||
return substr($a, 0, 1) . lcs(substr($a, 1), substr($b, 1));
|
||||
}
|
||||
my $c = lcs(substr($a, 1), $b) || "";
|
||||
my $d = lcs($a, substr($b, 1)) || "";
|
||||
return length($c) > length($d) ? $c : $d;
|
||||
}
|
||||
|
||||
my @a = split //, 'thisisatest';
|
||||
my @b = split //, 'testing123testing';
|
||||
|
||||
print LCS( \@a, \@b );
|
||||
print lcs("thisisatest", "testing123testing") . "\n";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
function Get-Lcs ($ReferenceObject, $DifferenceObject)
|
||||
{
|
||||
$longestCommonSubsequence = @()
|
||||
$x = $ReferenceObject.Length
|
||||
$y = $DifferenceObject.Length
|
||||
|
||||
$lengths = New-Object -TypeName 'System.Object[,]' -ArgumentList ($x + 1), ($y + 1)
|
||||
|
||||
for($i = 0; $i -lt $x; $i++)
|
||||
{
|
||||
for ($j = 0; $j -lt $y; $j++)
|
||||
{
|
||||
if ($ReferenceObject[$i] -ceq $DifferenceObject[$j])
|
||||
{
|
||||
$lengths[($i+1),($j+1)] = $lengths[$i,$j] + 1
|
||||
}
|
||||
else
|
||||
{
|
||||
$lengths[($i+1),($j+1)] = [Math]::Max(($lengths[($i+1),$j]),($lengths[$i,($j+1)]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (($x -ne 0) -and ($y -ne 0))
|
||||
{
|
||||
if ( $lengths[$x,$y] -eq $lengths[($x-1),$y])
|
||||
{
|
||||
--$x
|
||||
}
|
||||
elseif ($lengths[$x,$y] -eq $lengths[$x,($y-1)])
|
||||
{
|
||||
--$y
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($ReferenceObject[($x-1)] -ceq $DifferenceObject[($y-1)])
|
||||
{
|
||||
$longestCommonSubsequence = ,($ReferenceObject[($x-1)]) + $longestCommonSubsequence
|
||||
}
|
||||
|
||||
--$x
|
||||
--$y
|
||||
}
|
||||
}
|
||||
|
||||
$longestCommonSubsequence
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
(Get-Lcs -ReferenceObject "thisisatest" -DifferenceObject "testing123testing") -join ""
|
||||
|
|
@ -0,0 +1 @@
|
|||
Get-Lcs -ReferenceObject @(1,2,3,4) -DifferenceObject @(1,2,2,4,5,3,3,3,2,4)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
$list1
|
||||
|
||||
ID X Y
|
||||
-- - -
|
||||
1 101 201
|
||||
2 102 202
|
||||
3 103 203
|
||||
4 104 204
|
||||
5 105 205
|
||||
6 106 206
|
||||
7 107 207
|
||||
8 108 208
|
||||
9 109 209
|
||||
|
||||
$list2
|
||||
|
||||
ID X Y
|
||||
-- - -
|
||||
1 101 201
|
||||
3 103 203
|
||||
5 105 205
|
||||
7 107 207
|
||||
9 109 209
|
||||
|
||||
Get-Lcs -ReferenceObject $list1.ID -DifferenceObject $list2.ID
|
||||
|
|
@ -6,8 +6,7 @@ def lcs(a, b):
|
|||
if x == y:
|
||||
lengths[i+1][j+1] = lengths[i][j] + 1
|
||||
else:
|
||||
lengths[i+1][j+1] = \
|
||||
max(lengths[i+1][j], lengths[i][j+1])
|
||||
lengths[i+1][j+1] = max(lengths[i+1][j], lengths[i][j+1])
|
||||
# read the substring out from the matrix
|
||||
result = ""
|
||||
x, y = len(a), len(b)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
def lcs[T]: (List[T], List[T]) => List[T] = {
|
||||
case (_, Nil) => Nil
|
||||
case (Nil, _) => Nil
|
||||
case (x :: xs, y :: ys) if x == y => x :: lcs(xs, ys)
|
||||
case (x :: xs, y :: ys) => {
|
||||
(lcs(x :: xs, ys), lcs(xs, y :: ys)) match {
|
||||
case (xs, ys) if xs.length > ys.length => xs
|
||||
case (xs, ys) => ys
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
case class Memoized[A1, A2, B](f: (A1, A2) => B) extends ((A1, A2) => B) {
|
||||
val cache = scala.collection.mutable.Map.empty[(A1, A2), B]
|
||||
def apply(x: A1, y: A2) = cache.getOrElseUpdate((x, y), f(x, y))
|
||||
}
|
||||
|
||||
lazy val lcsM: Memoized[List[Char], List[Char], List[Char]] = Memoized {
|
||||
case (_, Nil) => Nil
|
||||
case (Nil, _) => Nil
|
||||
case (x :: xs, y :: ys) if x == y => x :: lcsM(xs, ys)
|
||||
case (x :: xs, y :: ys) => {
|
||||
(lcsM(x :: xs, ys), lcsM(xs, y :: ys)) match {
|
||||
case (xs, ys) if xs.length > ys.length => xs
|
||||
case (xs, ys) => ys
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
object LCS extends App {
|
||||
|
||||
// recursive version:
|
||||
def lcsr(a: String, b: String): String = {
|
||||
if (a.size==0 || b.size==0) ""
|
||||
else if (a==b) a
|
||||
else
|
||||
if(a(a.size-1)==b(b.size-1)) lcsr(a.substring(0,a.size-1),b.substring(0,b.size-1))+a(a.size-1)
|
||||
else {
|
||||
val x = lcsr(a,b.substring(0,b.size-1))
|
||||
val y = lcsr(a.substring(0,a.size-1),b)
|
||||
if (x.size > y.size) x else y
|
||||
}
|
||||
}
|
||||
|
||||
// dynamic programming version:
|
||||
def lcsd(a: String, b: String): String = {
|
||||
if (a.size==0 || b.size==0) ""
|
||||
else if (a==b) a
|
||||
else {
|
||||
val lengths = Array.ofDim[Int](a.size+1,b.size+1)
|
||||
for (i <- 0 until a.size)
|
||||
for (j <- 0 until b.size)
|
||||
if (a(i) == b(j))
|
||||
lengths(i+1)(j+1) = lengths(i)(j) + 1
|
||||
else
|
||||
lengths(i+1)(j+1) = scala.math.max(lengths(i+1)(j),lengths(i)(j+1))
|
||||
|
||||
// read the substring out from the matrix
|
||||
val sb = new StringBuilder()
|
||||
var x = a.size
|
||||
var y = b.size
|
||||
do {
|
||||
if (lengths(x)(y) == lengths(x-1)(y))
|
||||
x -= 1
|
||||
else if (lengths(x)(y) == lengths(x)(y-1))
|
||||
y -= 1
|
||||
else {
|
||||
assert(a(x-1) == b(y-1))
|
||||
sb += a(x-1)
|
||||
x -= 1
|
||||
y -= 1
|
||||
}
|
||||
} while (x!=0 && y!=0)
|
||||
sb.toString.reverse
|
||||
}
|
||||
}
|
||||
|
||||
val elapsed: (=> Unit) => Long = f => {val s = System.currentTimeMillis; f; (System.currentTimeMillis - s)/1000}
|
||||
|
||||
val pairs = List(("thisiaatest","testing123testing")
|
||||
,("","x")
|
||||
,("x","x")
|
||||
,("beginning-middle-ending", "beginning-diddle-dum-ending"))
|
||||
|
||||
var s = ""
|
||||
println("recursive version:")
|
||||
pairs foreach {p =>
|
||||
println{val t = elapsed(s = lcsr(p._1,p._2))
|
||||
"lcsr(\""+p._1+"\",\""+p._2+"\") = \""+s+"\" ("+t+" sec)"}
|
||||
}
|
||||
|
||||
println("\n"+"dynamic programming version:")
|
||||
pairs foreach {p =>
|
||||
println{val t = elapsed(s = lcsd(p._1,p._2))
|
||||
"lcsd(\""+p._1+"\",\""+p._2+"\") = \""+s+"\" ("+t+" sec)"}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue