void lcs(seq const & xs, seq const & ys, seq & an_lcs) { members xs_in_lcs(xs.size(), false); calculate_lcs(xs.begin(), xs.begin(), xs.end(), ys.begin(), ys.end(), xs_in_lcs); set_lcs(xs.begin(), xs_in_lcs, back_inserter(an_lcs)); }
void calculate_lcs(it xo, it xlo, it xhi, it ylo, it yhi, members & xs_in_lcs) { unsigned const nx = distance(xlo, xhi); if (nx == 0) { // empty range. all done } else if (nx == 1) { // single item in x range. // If it's in the yrange, mark its position in the LCS xs_in_lcs[distance(xo, xlo)] = find(ylo, yhi, *xlo) != yhi; } else { // split the xrange it xmid = xlo + nx / 2; // Find LCS lengths at xmid, working from both ends of the range lengths ll_b, ll_e; std::reverse_iterator<it> hix(xhi), midx(xmid), hiy(yhi), loy(ylo); lcs_lens(xlo, xmid, ylo, yhi, ll_b); lcs_lens(hix, midx, hiy, loy, ll_e); // Find the optimal place to split the y range lengths::const_reverse_iterator e = ll_e.rbegin(); int lmax = -1; it y = ylo, ymid = ylo; for (lengths::const_iterator b = ll_b.begin(); b != ll_b.end(); ++y, ++b, ++e) { if (*b + *e > lmax) { lmax = *b + *e; ymid = y; } } // Split the range and recurse calculate_lcs(xo, xlo, xmid, ylo, ymid, xs_in_lcs); calculate_lcs(xo, xmid, xhi, ymid, yhi, xs_in_lcs); } }
int main(int argc, char **argv) { char *a = "BDCABA"; char *b = "ABCBDAB"; int lcs; lcs = calculate_lcs(a, b); printf("LCS is %d\n", lcs); return 0; }