RosettaCodeData/Task/Longest-common-subsequence/D/longest-common-subsequence-3.d

62 lines
1.8 KiB
D
Raw Permalink Normal View History

2015-02-20 00:35:01 -05:00
import std.stdio, std.algorithm, std.range, std.array, std.string, std.typecons;
2013-06-05 21:47:54 +00:00
2015-02-20 00:35:01 -05:00
uint[] lensLCS(R)(R xs, R ys) pure nothrow @safe {
2013-10-27 22:24:23 +00:00
auto prev = new typeof(return)(1 + ys.length);
auto curr = new typeof(return)(1 + ys.length);
2013-06-05 21:47:54 +00:00
foreach (immutable x; xs) {
swap(curr, prev);
size_t i = 0;
foreach (immutable y; ys) {
2015-02-20 00:35:01 -05:00
curr[i + 1] = (x == y) ? prev[i] + 1 : max(curr[i], prev[i + 1]);
2013-06-05 21:47:54 +00:00
i++;
}
}
return curr;
}
void calculateLCS(T)(in T[] xs, in T[] ys, bool[] xs_in_lcs,
2015-02-20 00:35:01 -05:00
in size_t idx=0) pure nothrow @safe {
2013-06-05 21:47:54 +00:00
immutable nx = xs.length;
immutable ny = ys.length;
if (nx == 0)
return;
if (nx == 1) {
if (ys.canFind(xs[0]))
xs_in_lcs[idx] = true;
} else {
immutable mid = nx / 2;
2013-10-27 22:24:23 +00:00
const xb = xs[0.. mid];
const xe = xs[mid .. $];
immutable ll_b = lensLCS(xb, ys);
2013-06-05 21:47:54 +00:00
2015-02-20 00:35:01 -05:00
const ll_e = lensLCS(xe.retro, ys.retro); // retro is slow with dmd.
2013-06-05 21:47:54 +00:00
//immutable k = iota(ny + 1)
// .reduce!(max!(j => ll_b[j] + ll_e[ny - j]));
2013-10-27 22:24:23 +00:00
immutable k = iota(ny + 1)
2015-02-20 00:35:01 -05:00
.minPos!((i, j) => tuple(ll_b[i] + ll_e[ny - i]) >
tuple(ll_b[j] + ll_e[ny - j]))[0];
2013-06-05 21:47:54 +00:00
2013-10-27 22:24:23 +00:00
calculateLCS(xb, ys[0 .. k], xs_in_lcs, idx);
calculateLCS(xe, ys[k .. $], xs_in_lcs, idx + mid);
2013-06-05 21:47:54 +00:00
}
}
2015-02-20 00:35:01 -05:00
const(T)[] lcs(T)(in T[] xs, in T[] ys) pure /*nothrow*/ @safe {
2013-06-05 21:47:54 +00:00
auto xs_in_lcs = new bool[xs.length];
calculateLCS(xs, ys, xs_in_lcs);
2015-02-20 00:35:01 -05:00
return zip(xs, xs_in_lcs).filter!q{ a[1] }.map!q{ a[0] }.array; // Not nothrow.
2013-06-05 21:47:54 +00:00
}
2015-02-20 00:35:01 -05:00
string lcsString(in string s1, in string s2) pure /*nothrow*/ @safe {
return lcs(s1.representation, s2.representation).assumeUTF;
2013-06-05 21:47:54 +00:00
}
void main() {
lcsString("thisisatest", "testing123testing").writeln;
}