September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -5,7 +5,7 @@
#include <deque>
#include <map>
#include <algorithm> // for lower_bound()
#include <iterator> // for prev()
#include <iterator> // for next() and prev()
using namespace std;
@ -55,10 +55,10 @@ protected:
// Each of the index1, index2 pairs considered here correspond to a match
auto index2 = *it2;
//
//
// Note: The index2 values are monotonically decreasing, which allows the
// thresholds to be updated in place. Montonicity allows a binary search,
// implemented here by std::lower_bound()
// thresholds to be updated in-place. Monotonicity allows a binary search,
// implemented here by std::lower_bound().
//
limit = lower_bound(threshold.begin(), limit, index2);
auto index3 = distance(threshold.begin(), limit);
@ -72,14 +72,14 @@ protected:
// Depending on match redundancy, the number of Pair constructions may be
// divided by factors ranging from 2 up to 10 or more.
//
auto skip = it2 + 1 != dq2.end() &&
(limit == threshold.begin() || *(limit - 1) < *(it2 + 1));
auto skip = next(it2) != dq2.end() &&
(limit == threshold.begin() || *prev(limit) < *next(it2));
if (skip) continue;
if (limit == threshold.end()) {
// insert case
threshold.push_back(index2);
// Refresh limit iterator:
limit = prev(threshold.end());
if (trace) {
auto prefix = index3 > 0 ? traces[index3 - 1] : nullptr;
@ -136,7 +136,7 @@ protected:
string Select(shared_ptr<Pair> pairs, uint64_t length,
bool right, const string& s1, const string& s2) {
string buffer;
buffer.reserve(length);
buffer.reserve((uint32_t)length);
for (auto next = pairs; next != nullptr; next = next->next) {
auto c = right ? s2[next->index2] : s1[next->index1];
buffer.push_back(c);

View file

@ -1,33 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* lcs(const char *a, const char *b, char *out)
{
int longest = 0;
int match(const char *a, const char *b, int dep) {
if (!a || !b) return 0;
if (!*a || !*b) {
if (dep <= longest) return 0;
out[ longest = dep ] = 0;
return 1;
}
if (*a == *b)
return match(a + 1, b + 1, dep + 1) && (out[dep] = *a);
return match(a + 1, b + 1, dep) +
match(strchr(a, *b), b, dep) +
match(a, strchr(b, *a), dep);
}
return match(a, b, 0) ? out : 0;
}
int main()
{
char buf[128];
printf("%s\n", lcs("thisisatest", "testing123testing", buf));
printf("%p\n", lcs("no", "match", buf));
return 0;
}

View file

@ -1,10 +1,10 @@
(defn longest [xs ys] (if (> (count xs) (count ys)) xs ys))
(def lcs
(memoize
(fn [[x & xs] [y & ys]]
(cond
(or (= x nil) (= y nil) ) nil
(or (= x nil) (= y nil)) nil
(= x y) (cons x (lcs xs ys))
:else (longest (lcs (cons x xs) ys) (lcs xs (cons y ys)))))))
:else (longest (lcs (cons x xs) ys)
(lcs xs (cons y ys)))))))

View file

@ -0,0 +1,39 @@
-module(lcs).
%% API exports
-export([
lcs/2
]).
%%====================================================================
%% API functions
%%====================================================================
lcs(A, B) ->
{LCS, _Cache} = get_lcs(A, B, [], #{}),
lists:reverse(LCS).
%%====================================================================
%% Internal functions
%%=====================================================
get_lcs(A, B, Acc, Cache) ->
case maps:find({A, B, Acc}, Cache) of
{ok, LCS} -> {LCS, Cache};
error ->
{NewLCS, NewCache} = compute_lcs(A, B, Acc, Cache),
{NewLCS, NewCache#{ {A, B, Acc} => NewLCS }}
end.
compute_lcs(A, B, Acc, Cache) when length(A) == 0 orelse length(B) == 0 ->
{Acc, Cache};
compute_lcs([Token |ATail], [Token |BTail], Acc, Cache) ->
get_lcs(ATail, BTail, [Token |Acc], Cache);
compute_lcs([_AToken |ATail]=A, [_BToken |BTail]=B, Acc, Cache) ->
{LCSA, CacheA} = get_lcs(A, BTail, Acc, Cache),
{LCSB, CacheB} = get_lcs(ATail, B, Acc, CacheA),
LCS = case length(LCSA) > length(LCSB) of
true -> LCSA;
false -> LCSB
end,
{LCS, CacheB}.

View file

@ -0,0 +1,2 @@
48> lcs:lcs("thisisatest", "testing123testing").
"tsitest"

View file

@ -0,0 +1,57 @@
longest(a::String, b::String) = length(a) ≥ length(b) ? a : b
"""
julia> lcsrecursive("thisisatest", "testing123testing")
"tsitest"
"""
# Recursive
function lcsrecursive(xstr::String, ystr::String)
if length(xstr) == 0 || length(ystr) == 0
return ""
end
x, xs, y, ys = xstr[1], xstr[2:end], ystr[1], ystr[2:end]
if x == y
return string(x, lcsrecursive(xs, ys))
else
return longest(lcsrecursive(xstr, ys), lcsrecursive(xs, ystr))
end
end
# Dynamic
function lcsdynamic(a::String, b::String)
lengths = zeros(Int, length(a) + 1, length(b) + 1)
# row 0 and column 0 are initialized to 0 already
for (i, x) in enumerate(a), (j, y) in enumerate(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])
end
end
# read the substring out from the matrix
result = ""
x, y = length(a) + 1, length(b) + 1
while x > 1 && y > 1
if lengths[x, y] == lengths[x-1, y]
x -= 1
elseif lengths[x, y] == lengths[x, y-1]
y -= 1
else
@assert a[x-1] == b[y-1]
result = string(a[x-1], result)
x -= 1
y -= 1
end
end
return result
end
@show lcsrecursive("thisisatest", "testing123testing")
@time lcsrecursive("thisisatest", "testing123testing")
@show lcsdynamic("thisisatest", "testing123testing")
@time lcsdynamic("thisisatest", "testing123testing")

View file

@ -0,0 +1,17 @@
// version 1.1.2
fun lcs(x: String, y: String): String {
if (x.length == 0 || y.length == 0) return ""
val x1 = x.dropLast(1)
val y1 = y.dropLast(1)
if (x.last() == y.last()) return lcs(x1, y1) + x.last()
val x2 = lcs(x, y1)
val y2 = lcs(x1, y)
return if (x2.length > y2.length) x2 else y2
}
fun main(args: Array<String>) {
val x = "thisisatest"
val y = "testing123testing"
println(lcs(x, y))
}

View file

@ -0,0 +1,20 @@
function lcs(sequence a, b)
sequence res = ""
if length(a) and length(b) then
if a[$]=b[$] then
res = lcs(a[1..-2],b[1..-2])&a[$]
else
sequence l = lcs(a[1..-2],b),
r = lcs(a,b[1..-2])
res = iff(length(l)>length(r)?l:r)
end if
end if
return res
end function
constant tests = {{"1234","1224533324"},
{"thisisatest","testing123testing"}}
for i=1 to length(tests) do
string {a,b} = tests[i]
?lcs(a,b)
end for

View file

@ -0,0 +1,38 @@
function LCSLength(sequence X, sequence Y)
sequence C = repeat(repeat(0,length(Y)+1),length(X)+1)
for i=1 to length(X) do
for j=1 to length(Y) do
if X[i]=Y[j] then
C[i+1][j+1] := C[i][j]+1
else
C[i+1][j+1] := max(C[i+1][j], C[i][j+1])
end if
end for
end for
return C
end function
function backtrack(sequence C, sequence X, sequence Y, integer i, integer j)
if i=0 or j=0 then
return ""
elsif X[i]=Y[j] then
return backtrack(C, X, Y, i-1, j-1) & X[i]
else
if C[i+1][j]>C[i][j+1] then
return backtrack(C, X, Y, i, j-1)
else
return backtrack(C, X, Y, i-1, j)
end if
end if
end function
function lcs(sequence a, sequence b)
return backtrack(LCSLength(a,b),a,b,length(a),length(b))
end function
constant tests = {{"1234","1224533324"},
{"thisisatest","testing123testing"}}
for i=1 to length(tests) do
string {a,b} = tests[i]
?lcs(a,b)
end for

View file

@ -1,14 +0,0 @@
def lcs(a, b)
matrix = Array.new(a.length) { Array.new(b.length) }
walker = LcsWalker.new(matrix)
a.each_char.with_index do |x, i|
b.each_char.with_index do |y, j|
walker.pos(i, j)
walker.match(x, y)
end
end
walker.pos(a.length-1, b.length-1)
walker.backtrack.inject("") { |s, i| s.prepend(a[i]) }
end

View file

@ -0,0 +1,56 @@
use std::cmp;
fn lcs(string1: String, string2: String) -> (usize, String){
let total_rows = string1.len() + 1;
let total_columns = string2.len() + 1;
// rust doesn't allow accessing string by index
let string1_chars = string1.as_bytes();
let string2_chars = string2.as_bytes();
let mut table = vec![vec![0; total_columns]; total_rows];
for row in 1..total_rows{
for col in 1..total_columns {
if string1_chars[row - 1] == string2_chars[col - 1]{
table[row][col] = table[row - 1][col - 1] + 1;
} else {
table[row][col] = cmp::max(table[row][col-1], table[row-1][col]);
}
}
}
let mut common_seq = Vec::new();
let mut x = total_rows - 1;
let mut y = total_columns - 1;
while x != 0 && y != 0 {
// Check element above is equal
if table[x][y] == table[x - 1][y] {
x = x - 1;
}
// check element to the left is equal
else if table[x][y] == table[x][y - 1] {
y = y - 1;
}
else {
// check the two element at the respective x,y position is same
assert_eq!(string1_chars[x-1], string2_chars[y-1]);
let char = string1_chars[x - 1];
common_seq.push(char);
x = x - 1;
y = y - 1;
}
}
common_seq.reverse();
(table[total_rows - 1][total_columns - 1], String::from_utf8(common_seq).unwrap())
}
fn main() {
let res = lcs("abcdaf".to_string(), "acbcf".to_string());
assert_eq!((4 as usize, "abcf".to_string()), res);
let res = lcs("thisisatest".to_string(), "testing123testing".to_string());
assert_eq!((7 as usize, "tsitest".to_string()), res);
// LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length 4.
let res = lcs("AGGTAB".to_string(), "GXTXAYB".to_string());
assert_eq!((4 as usize, "GTAB".to_string()), res);
}

View file

@ -0,0 +1,22 @@
import <Utilities/Sequence.sl>;
lcsBack(a(1), b(1)) :=
let
aSub := allButLast(a);
bSub := allButLast(b);
x := lcsBack(a, bSub);
y := lcsBack(aSub, b);
in
[] when size(a) = 0 or size(b) = 0
else
lcsBack(aSub, bSub) ++ [last(a)] when last(a) = last(b)
else
x when size(x) > size(y)
else
y;
main(args(2)) :=
lcsBack(args[1], args[2]) when size(args) >=2
else
lcsBack("thisisatest", "testing123testing");

View file

@ -0,0 +1,5 @@
fcn lcs(a,b){
if(not a or not b) return("");
if (a[0]==b[0]) return(a[0] + self.fcn(a[1,*],b[1,*]));
return(fcn(x,y){if(x.len()>y.len())x else y}(lcs(a,b[1,*]),lcs(a[1,*],b)))
}