-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlcs.c
160 lines (133 loc) · 3.86 KB
/
lcs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "minunit/minunit.h"
#define NOTFOUND -1
/*
*Given two Strings,like X = ABCBDAB and Y = BCDDA
this program find the lengths of the longest common sequence of the two strings
eg: here longest common sequence is BCDA - with length 4
*/
/*
*This program uses the MinUnit library for unit testing the lcs function.
Also refer to the makefile. An extra -lrt flag has been added
*/
typedef size_t Length ;
typedef size_t Integer ; //it will be unsigned positive integr
int lcs_lookup ( char *strX, Length xlen, char *strY, Length ylen, int **c ) {
if (xlen == 0 || ylen == 0) {
return 0 ;
}
if ( c[xlen][ylen] != NOTFOUND ) {
return c[xlen][ylen] ; //the solution to this problem was already found
}
if ( strX[xlen-1] == strY[ylen-1] ) { //last array index = length of array - 1
c[xlen][ylen] = 1 + lcs_lookup(strX, xlen - 1, strY, ylen - 1, c) ;
return c[xlen][ylen] ;
}
Integer l1, l2 ;
l1 = lcs_lookup(strX, xlen, strY, ylen - 1, c ) ;
l2 = lcs_lookup(strX, xlen - 1, strY, ylen , c) ;
c[xlen][ylen] = (l1>=l2)?l1:l2 ;
return c[xlen][ylen] ;
}
/*This function finds th longest common subsequence of two strings X and Y */
int lcs( char *strX, char *strY ){
if (strX == NULL || strY == NULL) {
return 0 ;
}
Length xlen = strlen(strX) ;
Length ylen = strlen(strY);
int **c = (int **) calloc(xlen + 1 , sizeof(int *)) ;
Integer i, j ;
int lcs_len;
for (i = 0; i < xlen + 1; i++) {
c[i] = (int *)calloc(ylen + 1, sizeof(int) ) ;
}
// c is now an array of size (x_len + 1) * (y_len + 1)
// c[i][j] represents the length of lcs of substrings Xi and Yj
// c[i][0] for all i from i=1 to i=x_len and c[0][j] = 0 for all j from j=1 to j=y_len
// and c[0][0] = 0
c[0][0] = 0 ;
for (i = 1; i <= xlen; i++) {
c[i][0] = 0;
}
for(j=1; j <= ylen; j++ ) {
c[0][j] = 0;
}
for ( i = 1; i <= xlen; i++) {
for ( j= 1; j <= ylen; j++) {
c[i][j] = NOTFOUND ; //to indicate that we have to yet calculate them
}
}
// what we finally want to find out is c[xlen][ylen]
lcs_len = lcs_lookup(strX, xlen, strY, ylen, c) ;
for (i=0; i < xlen+1; i++) {
free(c[i]) ;
}
free(c) ;
return lcs_len ;
}
MU_TEST(test_lcs_normal){
char *X = "BACBADBA" ;
char *Y = "CDABC" ;
int l = lcs(X, Y ) ;
printf("\n l was %d \n ", l);
mu_check(l == 3) ;
}
MU_TEST(test_lcs_xempty){
char *X = "" ;
char *Y = "CDABC" ;
int l = lcs(X, Y) ;
printf("\n l was %d \n ", l);
mu_check(l == 0) ;
}
MU_TEST(test_lcs_yempty){
char *X = "BACBADBA" ;
char *Y = "" ;
int l = lcs(X, Y) ;
printf("\n l was %d \n ", l);
mu_check(l == 0) ;
}
MU_TEST(test_lcs_bothempty){
char *X = "" ;
char *Y = "" ;
int l = lcs(X, Y) ;
printf("\n l was %d \n ", l);
mu_check(l == 0) ;
}
MU_TEST(test_lcs_longX){
char *X = "BACBADBAABCBCABBAACABCADDABCBBDDBABADC" ;
char *Y = "CDABC" ;
int l = lcs(X, Y) ;
printf("\n l was %d \n ", l);
mu_check(l == 5) ;
}
MU_TEST(test_lcs_longY){
char *X = "BACBADBA" ;
char *Y = "CDABCBCDABCDABCDAADCNCDABCADCABCBDFDACNCAD" ;
int l = lcs(X, Y) ;
printf("\n l was %d \n ", l);
mu_check(l == 8) ;
}
MU_TEST(test_lcs_bothlong){
char *X = "BACBADBAABCBCABBAACABCADDABCBBDDBABADC" ;
char *Y = "CDABCBCDABCDABCDAADCNCDABCADCABCBDFDACNCAD" ;
int l = lcs(X, Y) ;
printf("\n l was %d in bothlong\n ", l);
mu_check(l == 27) ;
}
MU_TEST_SUITE(test_suite) {
MU_RUN_TEST(test_lcs_normal) ;
MU_RUN_TEST(test_lcs_xempty) ;
MU_RUN_TEST(test_lcs_yempty) ;
MU_RUN_TEST(test_lcs_bothempty) ;
MU_RUN_TEST(test_lcs_longX) ;
MU_RUN_TEST(test_lcs_longY) ;
MU_RUN_TEST(test_lcs_bothlong) ;
}
int main(){
MU_RUN_SUITE(test_suite) ;
MU_REPORT() ;
return 0 ;
}