/*************************************************************
* file:lcs.c
* brief:基于动态规划,求两个字符串的最长公共子序列
* yejing@2015.2.3 1.0 creat
*************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define MATRIX_MLEN 128
typedef enum{
DIR_UP,
DIR_LEFT,
DIR_UP_LEFT
}DIR_t;
void generate_lcs_matrix(char* str1, int len1, char* str2, int len2,
int lcs_matrix[][MATRIX_MLEN], int dir_matrix[][MATRIX_MLEN]){
int i = 0, j = 0;
if(len1 > MATRIX_MLEN || len2 > MATRIX_MLEN)
assert(0);
for(i = 0; i <= len1; ++i)
lcs_matrix[i][0] = 0;
for(j = 0; j <= len2; ++j)
lcs_matrix[0][j] = 0;
for(i = 1; i <= len1; ++i){
for(j = 1; j <= len2; ++j){
if(str1[i - 1] == str2[j - 1]){
lcs_matrix[i][j] = lcs_matrix[i - 1][j - 1] + 1;
dir_matrix[i][j] = DIR_UP_LEFT;
}
else if(lcs_matrix[i - 1][j] >= lcs_matrix[i][j - 1]){
dir_matrix[i][j] = DIR_UP;
lcs_matrix[i][j] = lcs_matrix[i - 1][j];
}
else{
dir_matrix[i][j] = DIR_LEFT;
lcs_matrix[i][j] = lcs_matrix[i][j - 1];
}
}
}
return;
}
void show_lcs(int dir_matrix[][MATRIX_MLEN], char* str1, int i, int j){
if(i == 0 || j == 0)
return;
if(dir_matrix[i][j] == DIR_UP_LEFT){
show_lcs(dir_matrix, str1, i - 1, j - 1);
printf("%c ", str1[i - 1]);
}
else if(dir_matrix[i][j] == DIR_LEFT){
show_lcs(dir_matrix, str1, i, j - 1);
}
else{
show_lcs(dir_matrix, str1, i - 1, j);
}
return;
}
int main(int argc, char* argv[]){
char* str1 = "aqswdefrgthyjukil";
char* str2 = "azsxdcfvgbhnjmkl";
int lcs_matrix[MATRIX_MLEN][MATRIX_MLEN];
int dir_matrix[MATRIX_MLEN][MATRIX_MLEN];
generate_lcs_matrix(str1, strlen(str1), str2, strlen(str2), lcs_matrix, dir_matrix);
show_lcs(dir_matrix, str1, strlen(str1), strlen(str2));
printf("\n");
return 1;
}