<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Longest Common Subsequence</title>
	<atom:link href="http://programmingpraxis.com/2009/06/09/longest-common-subsequence/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/</link>
	<description>A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmer</description>
	<lastBuildDate>Sat, 11 Feb 2012 09:48:16 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Vikas Tandi</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-2905</link>
		<dc:creator><![CDATA[Vikas Tandi]]></dc:creator>
		<pubDate>Sun, 24 Apr 2011 07:33:38 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-2905</guid>
		<description><![CDATA[my implementation in c
[sourcecode lang=&quot;cpp&quot;]
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

static int max(int x, int y);

int longest_common_subsequence(char *s, char *t, char *lcs)
{
	int i, j, k;
	int rowmax, colmax;
	int **matrix;

	/* calculate the matrix row size and column size */
	colmax = strlen(s) + 1;
	rowmax = strlen(t) + 1;

	/* allocate memory for the matrix */
	matrix = (int**)calloc(rowmax, sizeof(int*));

	if(matrix == NULL)
		return 0;

	for(k = 0; k &lt; rowmax; k++)
	{
		matrix[k] = (int*)calloc(colmax, sizeof(int));

		if(matrix[k] == NULL)
			return 0;
	}

	/* perform lcs operation on the matrix */
	for(i = 1; i &lt; rowmax; i++)
	{
		for(j = 1; j &lt; colmax; j++)
		{
			if(s[j-1] == t[i-1])
				matrix[i][j] = matrix[i-1][j-1] + 1;
			else
				matrix[i][j] = max(matrix[i-1][j], matrix[i][j-1]);
		}
	}

	/* backtrack the matrix to identify the largest common subsequence. */
	for(i = i-1, j = j-1, k = 0; i &#124;&#124; j;)
	{
		if(matrix[i-1][j] == matrix[i][j]	&amp;&amp;
			matrix[i][j-1] == matrix[i][j])
		{
			i--;
			j--;
		}
		else if(matrix[i-1][j] == matrix[i][j])
			i--;
		else if(matrix[i][j-1] == matrix[i][j])
			j--;
		else
		{
			lcs[k++] = t[i-1];
			i--;
			j--;
		}
	}
	lcs[k] = &#039;&#092;&#048;&#039;;
	strrev(lcs);
	return 1;
}

static int max(int x, int y)
{
	return (x &gt; y) ? x : y;
}

[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>my implementation in c</p>
<pre class="brush: cpp;">
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

static int max(int x, int y);

int longest_common_subsequence(char *s, char *t, char *lcs)
{
	int i, j, k;
	int rowmax, colmax;
	int **matrix;

	/* calculate the matrix row size and column size */
	colmax = strlen(s) + 1;
	rowmax = strlen(t) + 1;

	/* allocate memory for the matrix */
	matrix = (int**)calloc(rowmax, sizeof(int*));

	if(matrix == NULL)
		return 0;

	for(k = 0; k &lt; rowmax; k++)
	{
		matrix[k] = (int*)calloc(colmax, sizeof(int));

		if(matrix[k] == NULL)
			return 0;
	}

	/* perform lcs operation on the matrix */
	for(i = 1; i &lt; rowmax; i++)
	{
		for(j = 1; j &lt; colmax; j++)
		{
			if(s[j-1] == t[i-1])
				matrix[i][j] = matrix[i-1][j-1] + 1;
			else
				matrix[i][j] = max(matrix[i-1][j], matrix[i][j-1]);
		}
	}

	/* backtrack the matrix to identify the largest common subsequence. */
	for(i = i-1, j = j-1, k = 0; i || j;)
	{
		if(matrix[i-1][j] == matrix[i][j]	&amp;&amp;
			matrix[i][j-1] == matrix[i][j])
		{
			i--;
			j--;
		}
		else if(matrix[i-1][j] == matrix[i][j])
			i--;
		else if(matrix[i][j-1] == matrix[i][j])
			j--;
		else
		{
			lcs[k++] = t[i-1];
			i--;
			j--;
		}
	}
	lcs[k] = '&#092;&#048;';
	strrev(lcs);
	return 1;
}

static int max(int x, int y)
{
	return (x &gt; y) ? x : y;
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: OraQA &#187; Blog Archive &#187; How to find the Longest Common Subsequence (LCS) in SQL</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-1386</link>
		<dc:creator><![CDATA[OraQA &#187; Blog Archive &#187; How to find the Longest Common Subsequence (LCS) in SQL]]></dc:creator>
		<pubDate>Tue, 06 Jul 2010 00:08:59 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-1386</guid>
		<description><![CDATA[[...] Longest Common Subsequence  Finding the longest common subsequence of two sequences is a classic computer science problem with an equally classic solution that dates to the folklore of computing. The longest common subsequence is the longest set of elements that appear in order (not necessarily contiguous) in two sequences, the solution can be used in matching DNA sequences and it is also the basis of Unix &#8220;DIFF&#8221; utility. [...]]]></description>
		<content:encoded><![CDATA[<p>[...] Longest Common Subsequence  Finding the longest common subsequence of two sequences is a classic computer science problem with an equally classic solution that dates to the folklore of computing. The longest common subsequence is the longest set of elements that appear in order (not necessarily contiguous) in two sequences, the solution can be used in matching DNA sequences and it is also the basis of Unix &#8220;DIFF&#8221; utility. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jebb</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-1362</link>
		<dc:creator><![CDATA[Jebb]]></dc:creator>
		<pubDate>Sun, 27 Jun 2010 10:27:26 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-1362</guid>
		<description><![CDATA[I&#039;ve worked on a generic version of this in preparation for the 08 June 2010 exercise. I&#039;ve packed all the generic functions in a str_util.c file. The headers:
[sourcecode lang=&quot;cpp&quot;]
//str_util.h
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;
#define max(A,B) (((A) &gt; (B)) ? (A) : (B))
#define element(M, i, j) (*((M)-&gt;elt + \
		            ((M)-&gt;width * (i) + (j))))

typedef struct vector{
	int length;
	int *array;
} vector;
typedef struct matrix{
	int *elt;
	int width;
	int height;
} matrix;

void print_vector(vector *vec);
vector *lcs_indices(void *sequence1, 
				 void *sequence2, 
				 void *(*IndexFn)(void *, int),
				 int (*compFn)(void *, void *),
				 int (*lenFn)(void *));
static void scan_matrix(matrix *LCS, vector *vec);
static void print_matrix(matrix *arr);
static matrix *init_matrix(int width, int height);
static matrix *lcs_matrix(void *sequence1,
				   void *sequence2,
				   void *(*indexFn)(void *, int),
				   int (*compFn)(void *, void *),
				   int (*lenFn)(void *));
[/sourcecode]
the lcs_util.c file itself:
[sourcecode lang=&quot;cpp&quot;]
#include &quot;lcs_util.h&quot;
void print_vector(vector *vec)
{
	int i;
	for (i = 0; i &lt; vec-&gt;length; i++)
		printf(&quot;%d &quot;, vec-&gt;array[i]);
	printf(&quot;\n&quot;);
}

vector *lcs_indices(void *sequence1, 
				 void *sequence2, 
				 void *(*IndexFn)(void *, int),	//See comments in lcs_matrix
				 int (*compFn)(void *, void *),
				 int (*lenFn)(void *))
{
	vector *tmpvec;
	matrix *LCS;
	int test;
	LCS = lcs_matrix(sequence1, sequence2, IndexFn, compFn, lenFn);
	
	tmpvec = (vector *)malloc(sizeof(vector));
	assert(tmpvec != NULL);
	tmpvec-&gt;length = element(LCS, LCS-&gt;height - 1, LCS-&gt;width - 1);
	tmpvec-&gt;array = (int *)malloc((tmpvec-&gt;length) * sizeof(int));
	assert(tmpvec-&gt;array != NULL);

	scan_matrix(LCS, tmpvec);
	free(LCS-&gt;elt);
	free(LCS);
	return tmpvec;
}

static void scan_matrix(matrix *LCS, vector *vec)
{
	int row, col, i;
	row = LCS-&gt;height - 1;	//first row and column full of 0s
	col = LCS-&gt;width - 1;
	i = vec-&gt;length - 1;
	while (i &gt;= 0) {
		while (element(LCS, row, col) == element(LCS, row - 1, col))
			row--;
		while (element(LCS, row, col) == element(LCS, row, col - 1))
			col--;
		vec-&gt;array[i--] = col - 1; //index the array from 0
		col--;
		row--;
	}
}

static void print_matrix(matrix *arr)
{
	int row, col;
	for (row = 0; row &lt; arr-&gt;height; ++row) {
		printf(&quot;%d: &quot;, row);
		for (col = 0; col &lt; arr-&gt;width; ++col)
			printf(&quot;%d &quot;, element(arr, row, col));
		printf(&quot;\n&quot;);
	}
}

static matrix *init_matrix(int width, int height)
{
	matrix *tmpLCS;
	tmpLCS = (matrix *)malloc(sizeof(matrix));
	tmpLCS-&gt;elt = (int *)malloc(width * height * sizeof(int));
	assert(tmpLCS != NULL);
	assert(tmpLCS-&gt;elt != NULL);
	tmpLCS-&gt;width = width;
	tmpLCS-&gt;height = height;
	return tmpLCS;
}

static matrix *lcs_matrix(void *sequence1, 
				   void *sequence2, 
				   void *(*indexFn)(void *, int i), 
				   int (*compFn)(void *, void *), 
				   int (*lenFn)(void *))
/* Initialises and returns the matrix of minimum edit distances 
 * lenFn applies to a sequence: &quot;programming&quot; or &quot;praxis&quot;,
 * 		or a text seen as a sequence of lines
 * compFn compares two items in a sequence: letters in &quot;programming&quot; 
 * 		or &quot;praxis&quot;, or lines in a text sequence
 * indexFn returns a pointer to an item in a sequence: 
 * 		a letter in &quot;programming&quot;, 
 * 		a (char *) to a line in a text sequence */
{
	int row, col;
	matrix *tmpLCS;
	tmpLCS = init_matrix(lenFn(sequence1) + 1,
						 lenFn(sequence2) + 1);
	for (row = 0; row &lt; tmpLCS-&gt;height; ++row) {
		for (col = 0; col &lt; tmpLCS-&gt;width; ++col) {
			if ((row == 0) &#124;&#124; (col == 0))
				element (tmpLCS, row, col) = 0;
			else if (compFn(indexFn(sequence1, col - 1), 
				            indexFn(sequence2, row - 1)) == 0)
				element(tmpLCS, row, col) =
						element(tmpLCS, row - 1, col - 1) + 1;
			else
				element(tmpLCS, row, col) = 
							max(element(tmpLCS, row -1, col),
							    element(tmpLCS, row, col - 1));
		}
	}
	return tmpLCS;
}
[/sourcecode]
...and (finally) the string-specific bits:
[sourcecode lang=&quot;cpp&quot;]
#include &quot;lcs_util.h&quot;
int lenStr(void *str);
void *indexStr(void *str, int i);
int compStr(void *str1, void *str2);
void print_str(char *str, vector *lcs);

int main(int argc, char* argv[])
{
	vector *lcs;
	if (argc != 3) {
		printf(&quot;usage: lcs &lt;string 1&gt; &lt;string 2&gt;\n&quot;);
		exit(EXIT_FAILURE);
	}
	lcs = lcs_indices((void *)argv[1],
					  (void *)argv[2],
					  indexStr,
					  compStr,
					  lenStr);
	printf(&quot;Longest common sequence: &quot;); 
	print_str(argv[1], lcs);
	free(lcs-&gt;array);
	free(lcs);
	exit(EXIT_SUCCESS);
}

void print_str(char *str, vector *lcs)
{
	int *ip;
	for (ip = lcs-&gt;array; ip - lcs-&gt;array &lt; lcs-&gt;length; ip++)
		putchar(str[*ip]);
	putchar(&#039;\n&#039;);
}

int lenStr(void *str)
{
	return strlen((char *)str);
}

void *indexStr(void *str, int i)
{
	char *cp;
	cp = (char *)str + i * sizeof(char);
	return (void *)cp;
}

int compStr(void *str1, void *str2)
{
	return (int)(*((char *)str1) - *((char *)str2));
}
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>I&#8217;ve worked on a generic version of this in preparation for the 08 June 2010 exercise. I&#8217;ve packed all the generic functions in a str_util.c file. The headers:</p>
<pre class="brush: cpp;">
//str_util.h
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;
#define max(A,B) (((A) &gt; (B)) ? (A) : (B))
#define element(M, i, j) (*((M)-&gt;elt + \
		            ((M)-&gt;width * (i) + (j))))

typedef struct vector{
	int length;
	int *array;
} vector;
typedef struct matrix{
	int *elt;
	int width;
	int height;
} matrix;

void print_vector(vector *vec);
vector *lcs_indices(void *sequence1,
				 void *sequence2,
				 void *(*IndexFn)(void *, int),
				 int (*compFn)(void *, void *),
				 int (*lenFn)(void *));
static void scan_matrix(matrix *LCS, vector *vec);
static void print_matrix(matrix *arr);
static matrix *init_matrix(int width, int height);
static matrix *lcs_matrix(void *sequence1,
				   void *sequence2,
				   void *(*indexFn)(void *, int),
				   int (*compFn)(void *, void *),
				   int (*lenFn)(void *));
</pre>
<p>the lcs_util.c file itself:</p>
<pre class="brush: cpp;">
#include &quot;lcs_util.h&quot;
void print_vector(vector *vec)
{
	int i;
	for (i = 0; i &lt; vec-&gt;length; i++)
		printf(&quot;%d &quot;, vec-&gt;array[i]);
	printf(&quot;\n&quot;);
}

vector *lcs_indices(void *sequence1,
				 void *sequence2,
				 void *(*IndexFn)(void *, int),	//See comments in lcs_matrix
				 int (*compFn)(void *, void *),
				 int (*lenFn)(void *))
{
	vector *tmpvec;
	matrix *LCS;
	int test;
	LCS = lcs_matrix(sequence1, sequence2, IndexFn, compFn, lenFn);

	tmpvec = (vector *)malloc(sizeof(vector));
	assert(tmpvec != NULL);
	tmpvec-&gt;length = element(LCS, LCS-&gt;height - 1, LCS-&gt;width - 1);
	tmpvec-&gt;array = (int *)malloc((tmpvec-&gt;length) * sizeof(int));
	assert(tmpvec-&gt;array != NULL);

	scan_matrix(LCS, tmpvec);
	free(LCS-&gt;elt);
	free(LCS);
	return tmpvec;
}

static void scan_matrix(matrix *LCS, vector *vec)
{
	int row, col, i;
	row = LCS-&gt;height - 1;	//first row and column full of 0s
	col = LCS-&gt;width - 1;
	i = vec-&gt;length - 1;
	while (i &gt;= 0) {
		while (element(LCS, row, col) == element(LCS, row - 1, col))
			row--;
		while (element(LCS, row, col) == element(LCS, row, col - 1))
			col--;
		vec-&gt;array[i--] = col - 1; //index the array from 0
		col--;
		row--;
	}
}

static void print_matrix(matrix *arr)
{
	int row, col;
	for (row = 0; row &lt; arr-&gt;height; ++row) {
		printf(&quot;%d: &quot;, row);
		for (col = 0; col &lt; arr-&gt;width; ++col)
			printf(&quot;%d &quot;, element(arr, row, col));
		printf(&quot;\n&quot;);
	}
}

static matrix *init_matrix(int width, int height)
{
	matrix *tmpLCS;
	tmpLCS = (matrix *)malloc(sizeof(matrix));
	tmpLCS-&gt;elt = (int *)malloc(width * height * sizeof(int));
	assert(tmpLCS != NULL);
	assert(tmpLCS-&gt;elt != NULL);
	tmpLCS-&gt;width = width;
	tmpLCS-&gt;height = height;
	return tmpLCS;
}

static matrix *lcs_matrix(void *sequence1,
				   void *sequence2,
				   void *(*indexFn)(void *, int i),
				   int (*compFn)(void *, void *),
				   int (*lenFn)(void *))
/* Initialises and returns the matrix of minimum edit distances
 * lenFn applies to a sequence: &quot;programming&quot; or &quot;praxis&quot;,
 * 		or a text seen as a sequence of lines
 * compFn compares two items in a sequence: letters in &quot;programming&quot;
 * 		or &quot;praxis&quot;, or lines in a text sequence
 * indexFn returns a pointer to an item in a sequence:
 * 		a letter in &quot;programming&quot;,
 * 		a (char *) to a line in a text sequence */
{
	int row, col;
	matrix *tmpLCS;
	tmpLCS = init_matrix(lenFn(sequence1) + 1,
						 lenFn(sequence2) + 1);
	for (row = 0; row &lt; tmpLCS-&gt;height; ++row) {
		for (col = 0; col &lt; tmpLCS-&gt;width; ++col) {
			if ((row == 0) || (col == 0))
				element (tmpLCS, row, col) = 0;
			else if (compFn(indexFn(sequence1, col - 1),
				            indexFn(sequence2, row - 1)) == 0)
				element(tmpLCS, row, col) =
						element(tmpLCS, row - 1, col - 1) + 1;
			else
				element(tmpLCS, row, col) =
							max(element(tmpLCS, row -1, col),
							    element(tmpLCS, row, col - 1));
		}
	}
	return tmpLCS;
}
</pre>
<p>&#8230;and (finally) the string-specific bits:</p>
<pre class="brush: cpp;">
#include &quot;lcs_util.h&quot;
int lenStr(void *str);
void *indexStr(void *str, int i);
int compStr(void *str1, void *str2);
void print_str(char *str, vector *lcs);

int main(int argc, char* argv[])
{
	vector *lcs;
	if (argc != 3) {
		printf(&quot;usage: lcs &lt;string 1&gt; &lt;string 2&gt;\n&quot;);
		exit(EXIT_FAILURE);
	}
	lcs = lcs_indices((void *)argv[1],
					  (void *)argv[2],
					  indexStr,
					  compStr,
					  lenStr);
	printf(&quot;Longest common sequence: &quot;);
	print_str(argv[1], lcs);
	free(lcs-&gt;array);
	free(lcs);
	exit(EXIT_SUCCESS);
}

void print_str(char *str, vector *lcs)
{
	int *ip;
	for (ip = lcs-&gt;array; ip - lcs-&gt;array &lt; lcs-&gt;length; ip++)
		putchar(str[*ip]);
	putchar('\n');
}

int lenStr(void *str)
{
	return strlen((char *)str);
}

void *indexStr(void *str, int i)
{
	char *cp;
	cp = (char *)str + i * sizeof(char);
	return (void *)cp;
}

int compStr(void *str1, void *str2)
{
	return (int)(*((char *)str1) - *((char *)str2));
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jebb</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-1339</link>
		<dc:creator><![CDATA[Jebb]]></dc:creator>
		<pubDate>Sat, 19 Jun 2010 11:50:14 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-1339</guid>
		<description><![CDATA[Ooooops... memory management bits me in the backside.

Lines 6 &amp; 7 should read

  7 #define element(M, i, j) (*((M)-&gt;elt + \
  8                             ((M)-&gt;width * (i) + (j))))
                           
Nasty bug there, the sizeof(int) in the macro I&#039;d initially written was completely uncalled for: gcc knows perfectly well already that (M)-&gt;elt is an int*. As a result, my code was writing the matrix to an area 4 times the size of what I&#039;d malloc&#039;d in init_matrix.]]></description>
		<content:encoded><![CDATA[<p>Ooooops&#8230; memory management bits me in the backside.</p>
<p>Lines 6 &amp; 7 should read</p>
<p>  7 #define element(M, i, j) (*((M)-&gt;elt + \<br />
  8                             ((M)-&gt;width * (i) + (j))))</p>
<p>Nasty bug there, the sizeof(int) in the macro I&#8217;d initially written was completely uncalled for: gcc knows perfectly well already that (M)-&gt;elt is an int*. As a result, my code was writing the matrix to an area 4 times the size of what I&#8217;d malloc&#8217;d in init_matrix.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jebb</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-1319</link>
		<dc:creator><![CDATA[Jebb]]></dc:creator>
		<pubDate>Sat, 12 Jun 2010 14:15:20 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-1319</guid>
		<description><![CDATA[[sourcecode lang=&quot;cpp&quot;]
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;
#define max(A,B) (((A) &gt; (B)) ? (A) : (B))
#define element(M, i, j) (*((M)-&gt;elt + \
						    ((M)-&gt;width * (i) + (j)) * sizeof(int)))

typedef struct matrix {
	int *elt;
	int width;
	int height;
} matrix;

char *longest_comm_seq(char *str1, char *str2);
matrix *init_matrix(int width, int length);
matrix *lcs_matrix(char *str1, char *str2);
void scan_matrix(matrix *LCS, char *str1, char *tmpchar);

int main(int argc, char* argv[])
{
	char *lcs;
	if (argc != 3) {
		printf(&quot;usage: lcs &lt;string 1&gt; &lt;string 2&gt;\n&quot;);
		exit(EXIT_FAILURE);
	}
	lcs = longest_comm_seq(argv[1], argv[2]);
	printf(&quot;Longest common sequence: \&quot;%s\&quot;\n&quot;, lcs); 
	free(lcs);
	exit(EXIT_SUCCESS);
}

char *longest_comm_seq(char *str1, char *str2)
{
	char *tmpchar;
	int lcsLength;
	matrix *LCS;
	LCS = lcs_matrix(str1, str2);
	lcsLength = element(LCS, LCS-&gt;height - 1, LCS-&gt;width - 1);
	tmpchar = (char *)malloc((lcsLength + 1) * sizeof(char));
	assert(tmpchar != NULL);
	scan_matrix(LCS, str1, tmpchar);
	free(LCS-&gt;elt);
	free(LCS);
	return tmpchar;
}

void scan_matrix(matrix *LCS, char *str1, char *tmpchar)
{
	int row, col, i;
	row = LCS-&gt;height - 1;
	col = LCS-&gt;width - 1;
	i = element(LCS, row, col);
	tmpchar[i--] = &#039;&#092;&#048;&#039;;
	while (i &gt;= 0) {
		while (element(LCS, row, col) == element(LCS, row - 1, col))
			row--;
		while (element(LCS, row, col) == element(LCS, row, col - 1))
			col--;
		tmpchar[i] = str1[col - 1];
		col--;
		row--;
		i--;
	}
}

matrix *init_matrix(int width, int height)
{
	matrix *tmpLCS;
	tmpLCS = (matrix *)malloc(sizeof(matrix));
	tmpLCS-&gt;elt = (int *)malloc(width * height * sizeof(int));
	assert(tmpLCS != NULL);
	assert(tmpLCS-&gt;elt != NULL);
	tmpLCS-&gt;width = width;
	tmpLCS-&gt;height = height;
	return tmpLCS;
}

matrix *lcs_matrix(char *str1, char *str2)
{
	int row, col;
	matrix *tmpLCS;
	tmpLCS = init_matrix(strlen(str1) + 1,
						 strlen(str2) + 1);
	for (row = 0; row &lt; tmpLCS-&gt;height; ++row) {
		for (col = 0; col &lt; tmpLCS-&gt;width; ++col) {
			if ((row == 0) &#124;&#124; (col == 0))
				element (tmpLCS, row, col) = 0;
			else if (str1[col - 1] == str2[row - 1])
				element(tmpLCS, row, col) =
						element(tmpLCS, row - 1, col - 1) + 1;
			else
				element(tmpLCS, row, col) = 
							max(element(tmpLCS, row -1, col),
							    element(tmpLCS, row, col - 1));
		}
	}
	return tmpLCS;
}
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<pre class="brush: cpp;">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;
#define max(A,B) (((A) &gt; (B)) ? (A) : (B))
#define element(M, i, j) (*((M)-&gt;elt + \
						    ((M)-&gt;width * (i) + (j)) * sizeof(int)))

typedef struct matrix {
	int *elt;
	int width;
	int height;
} matrix;

char *longest_comm_seq(char *str1, char *str2);
matrix *init_matrix(int width, int length);
matrix *lcs_matrix(char *str1, char *str2);
void scan_matrix(matrix *LCS, char *str1, char *tmpchar);

int main(int argc, char* argv[])
{
	char *lcs;
	if (argc != 3) {
		printf(&quot;usage: lcs &lt;string 1&gt; &lt;string 2&gt;\n&quot;);
		exit(EXIT_FAILURE);
	}
	lcs = longest_comm_seq(argv[1], argv[2]);
	printf(&quot;Longest common sequence: \&quot;%s\&quot;\n&quot;, lcs);
	free(lcs);
	exit(EXIT_SUCCESS);
}

char *longest_comm_seq(char *str1, char *str2)
{
	char *tmpchar;
	int lcsLength;
	matrix *LCS;
	LCS = lcs_matrix(str1, str2);
	lcsLength = element(LCS, LCS-&gt;height - 1, LCS-&gt;width - 1);
	tmpchar = (char *)malloc((lcsLength + 1) * sizeof(char));
	assert(tmpchar != NULL);
	scan_matrix(LCS, str1, tmpchar);
	free(LCS-&gt;elt);
	free(LCS);
	return tmpchar;
}

void scan_matrix(matrix *LCS, char *str1, char *tmpchar)
{
	int row, col, i;
	row = LCS-&gt;height - 1;
	col = LCS-&gt;width - 1;
	i = element(LCS, row, col);
	tmpchar[i--] = '&#092;&#048;';
	while (i &gt;= 0) {
		while (element(LCS, row, col) == element(LCS, row - 1, col))
			row--;
		while (element(LCS, row, col) == element(LCS, row, col - 1))
			col--;
		tmpchar[i] = str1[col - 1];
		col--;
		row--;
		i--;
	}
}

matrix *init_matrix(int width, int height)
{
	matrix *tmpLCS;
	tmpLCS = (matrix *)malloc(sizeof(matrix));
	tmpLCS-&gt;elt = (int *)malloc(width * height * sizeof(int));
	assert(tmpLCS != NULL);
	assert(tmpLCS-&gt;elt != NULL);
	tmpLCS-&gt;width = width;
	tmpLCS-&gt;height = height;
	return tmpLCS;
}

matrix *lcs_matrix(char *str1, char *str2)
{
	int row, col;
	matrix *tmpLCS;
	tmpLCS = init_matrix(strlen(str1) + 1,
						 strlen(str2) + 1);
	for (row = 0; row &lt; tmpLCS-&gt;height; ++row) {
		for (col = 0; col &lt; tmpLCS-&gt;width; ++col) {
			if ((row == 0) || (col == 0))
				element (tmpLCS, row, col) = 0;
			else if (str1[col - 1] == str2[row - 1])
				element(tmpLCS, row, col) =
						element(tmpLCS, row - 1, col - 1) + 1;
			else
				element(tmpLCS, row, col) =
							max(element(tmpLCS, row -1, col),
							    element(tmpLCS, row, col - 1));
		}
	}
	return tmpLCS;
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mike</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-1315</link>
		<dc:creator><![CDATA[Mike]]></dc:creator>
		<pubDate>Wed, 09 Jun 2010 18:35:08 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-1315</guid>
		<description><![CDATA[My Python version.  Incorporates a couple optimizations:

    1. identifies matching sequences at start and end of the two input sequences, and only runs LCS algorithm on the middle portions of the input sequences.

    2. a row of the matrix in the LCS algorithm only depends on the previous row, so only keep one previous row instead of entire matrix.

The LCS algorithm accumulates the indices of the members of the LCS. The reduce call at the end, assembles the LCS from the indices. The result has the same type (i.e., string, list, tuple) as seq1.
    
[sourcecode land=&quot;python&quot;]
from operator import add

def lcs(seq1, seq2):
    &quot;&quot;&quot;return longest common subsequence of seq1 and seq2.

    return type is the same as seq1

    &gt;&gt;&gt; lcs(&quot;programming&quot;, &quot;praxis&quot;)
    &#039;prai&#039;
    &gt;&gt;&gt; lcs(&quot;abcDzFjkl&quot;,&quot;abcGzIjkl&quot;)
    &#039;abczjkl&#039;
    &quot;&quot;&quot;

    start = 0
    while seq1[start] == seq2[start]:
        start += 1

    end1, end2 = len(seq1) - 1, len(seq2) - 1
    while seq1[end1] == seq2[end2]:
        end1 -= 1
        end2 -= 1

    row = [ [] ] * (end2 - start + 1)

    for r in range(start, end1):
        prev = row
        row = [ [] ]
        for c in range(start, end2):
            if seq1[r] == seq2[c]:
                row.append(prev[c - start] + [r])
            else:
                row.append(max(prev[c - start +1], row[-1], key=len))

    seq = reduce(add, (seq1[i:i + 1] for i in row[-1]))

    return seq1[:start] + seq + seq1[end1 + 1:]

if __name__ == &quot;__main__&quot;:
    import doctest
    print doctest.testmod()
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Python version.  Incorporates a couple optimizations:</p>
<p>    1. identifies matching sequences at start and end of the two input sequences, and only runs LCS algorithm on the middle portions of the input sequences.</p>
<p>    2. a row of the matrix in the LCS algorithm only depends on the previous row, so only keep one previous row instead of entire matrix.</p>
<p>The LCS algorithm accumulates the indices of the members of the LCS. The reduce call at the end, assembles the LCS from the indices. The result has the same type (i.e., string, list, tuple) as seq1.</p>
<pre class="brush: plain;">
from operator import add

def lcs(seq1, seq2):
    &quot;&quot;&quot;return longest common subsequence of seq1 and seq2.

    return type is the same as seq1

    &gt;&gt;&gt; lcs(&quot;programming&quot;, &quot;praxis&quot;)
    'prai'
    &gt;&gt;&gt; lcs(&quot;abcDzFjkl&quot;,&quot;abcGzIjkl&quot;)
    'abczjkl'
    &quot;&quot;&quot;

    start = 0
    while seq1[start] == seq2[start]:
        start += 1

    end1, end2 = len(seq1) - 1, len(seq2) - 1
    while seq1[end1] == seq2[end2]:
        end1 -= 1
        end2 -= 1

    row = [ [] ] * (end2 - start + 1)

    for r in range(start, end1):
        prev = row
        row = [ [] ]
        for c in range(start, end2):
            if seq1[r] == seq2[c]:
                row.append(prev[c - start] + [r])
            else:
                row.append(max(prev[c - start +1], row[-1], key=len))

    seq = reduce(add, (seq1[i:i + 1] for i in row[-1]))

    return seq1[:start] + seq + seq1[end1 + 1:]

if __name__ == &quot;__main__&quot;:
    import doctest
    print doctest.testmod()
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Programming Praxis &#8211; Longest Common Subsequence &#171; Bonsai Code</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-166</link>
		<dc:creator><![CDATA[Programming Praxis &#8211; Longest Common Subsequence &#171; Bonsai Code]]></dc:creator>
		<pubDate>Tue, 09 Jun 2009 21:19:31 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-166</guid>
		<description><![CDATA[[...] Praxis &#8211; Longest Common&#160;Subsequence By Remco Niemeijer  Today’s Programming Praxis problem is about finding the longest common subsequence of two sequences. Our [...]]]></description>
		<content:encoded><![CDATA[<p>[...] Praxis &#8211; Longest Common&nbsp;Subsequence By Remco Niemeijer  Today’s Programming Praxis problem is about finding the longest common subsequence of two sequences. Our [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2009/06/09/longest-common-subsequence/#comment-165</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Tue, 09 Jun 2009 18:28:37 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=716#comment-165</guid>
		<description><![CDATA[My Haskell solution (see http://bonsaicode.wordpress.com/2009/06/09/programming-praxis-longest-common-subsequence/ for a version with comments):

[sourcecode lang=&#039;css&#039;]
import Data.Array

at :: Int -&gt; Int -&gt; Array Int (Array Int e) -&gt; e
at x y a = a ! y ! x

lcs :: Eq a =&gt; [a] -&gt; [a] -&gt; [a]
lcs xs ys = reverse $ walk imax jmax where
    imax = length xs
    jmax = length ys
    ax = listArray (1, imax) xs
    ay = listArray (1, jmax) ys
    ls = listArray (0, jmax) [listArray (0, imax)
               [lcs&#039; i j &#124; i &lt;- [0..imax]] &#124; j &lt;- [0..jmax]]

    lcs&#039; 0 _ = 0
    lcs&#039; _ 0 = 0
    lcs&#039; i j &#124; ax ! i == ay ! j = 1 + at (i-1) (j-1) ls
             &#124; otherwise        = max (at (i-1) j ls) (at i (j-1) ls)
    
    walk 0 _ = []
    walk _ 0 = []
    walk i j &#124; at (i-1) j ls == at i j ls = walk (i-1) j
             &#124; at i (j-1) ls  &lt; at i j ls = ax ! i : walk i (j-1)
             &#124; otherwise                  = walk i (j-1)

main :: IO ()
main = print $ lcs &quot;programming&quot; &quot;praxis&quot;
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Haskell solution (see <a href="http://bonsaicode.wordpress.com/2009/06/09/programming-praxis-longest-common-subsequence/" rel="nofollow">http://bonsaicode.wordpress.com/2009/06/09/programming-praxis-longest-common-subsequence/</a> for a version with comments):</p>
<pre class="brush: css;">
import Data.Array

at :: Int -&gt; Int -&gt; Array Int (Array Int e) -&gt; e
at x y a = a ! y ! x

lcs :: Eq a =&gt; [a] -&gt; [a] -&gt; [a]
lcs xs ys = reverse $ walk imax jmax where
    imax = length xs
    jmax = length ys
    ax = listArray (1, imax) xs
    ay = listArray (1, jmax) ys
    ls = listArray (0, jmax) [listArray (0, imax)
               [lcs' i j | i &lt;- [0..imax]] | j &lt;- [0..jmax]]

    lcs' 0 _ = 0
    lcs' _ 0 = 0
    lcs' i j | ax ! i == ay ! j = 1 + at (i-1) (j-1) ls
             | otherwise        = max (at (i-1) j ls) (at i (j-1) ls)

    walk 0 _ = []
    walk _ 0 = []
    walk i j | at (i-1) j ls == at i j ls = walk (i-1) j
             | at i (j-1) ls  &lt; at i j ls = ax ! i : walk i (j-1)
             | otherwise                  = walk i (j-1)

main :: IO ()
main = print $ lcs &quot;programming&quot; &quot;praxis&quot;
</pre>
]]></content:encoded>
	</item>
</channel>
</rss>

