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
|
#include <iostream>
#include <fstream>
#include <string>
// recursively prints the actual subsequence
void printLCS(int** b, std::string x, size_t r, size_t c) {
if (r==0 or c==0)
return;
int val = b[r][c];
if (val==2){
printLCS(b, x, r-1, c-1);
std::cout << x[r];
}
else if (val==3)
printLCS(b, x, r-1, c);
else
printLCS(b, x, r, c-1);
}
// lcs func calculates length of lcs
void lcs(const std::string x, const std::string y, const size_t m, const size_t n) {
if(m==0 || n==0) {
std::cerr << "Both strings must be at least one character in length." << std::endl;
exit(1);
}
// dynamically create arrays of pointers of size m
int **b = new int*[m];
int **c = new int*[n];
// dynamically allocate memory of size n for each row
for (int i=0; i < m; i++) {
b[i] = new int[n];
c[i] = new int[n];
}
// assign values to allocated memory
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
c[i][j] = 0;
b[i][j] = 0;
}
}
// Main loop
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
if (x[i] == y[j]) {
c[i][j] = c[i-1][j-1] + 1;
b[i][j] = 2;
}
else if (c[i-1][j] > c[i][j-1]) {
c[i][j] = c[i-1][j];
b[i][j] = 3;
}
else {
c[i][j] = c[i][j-1];
b[i][j] = 1;
}
}
} // end of main loop
// print LCS
printLCS(b, x, m-1, n-1);
std::cout << std::endl;
// deallocating arrays
for (int i = 0; i < m; i++) {
delete[] b[i];
delete[] c[i];
}
delete[] b;
delete[] c;
b = NULL;
c = NULL;
} // end of lcs function
// Driver program
int main(int argc, const char * argv[]) {
if (argc != 3) {
std::cerr << "Provide 2 input file names for command line args." << std::endl;
exit(1);
}
// Prepare file streams
std::ifstream infile1(argv[1]);
std::ifstream infile2(argv[2]);
// If problem with either input file, exit
if( !infile1.good() || !infile2.good() ) {
std::cerr << "Invalid input file" << std::endl;
exit(1);
}
// Gets first line of each file into str1 and str2
std::string str1 = " ";
std::string str2 = " ";
std::string temp;
getline(infile1, temp);
str1.append(temp);
getline(infile2, temp);
str2.append(temp);
// Cleaning up
infile1.close();
infile2.close();
// Get length of both strings
size_t m = str1.length();
size_t n = str2.length();
// Calculate LCS
lcs(str1, str2, m, n);
return 0;
}
| |