/* * Josh Holtrop * 2008-10-01 * Grand Valley State University * CS677 * Programming Assignment #2 */ #include #include #include #include using namespace std; #define eq(x, y) ( ( (x) == (y) ) || ( (x) == '?' ) || ( (y) == '?' ) ) typedef struct { vector * s; vector * t; int id; void * matrix; } SMArg; void usage(char * prog); void * calcSimMatrixThread(void * arg); bool readFile(char * fileName, vector & v); pthread_barrier_t barrier; /* Print basic usage information */ void usage(char * prog) { cout << "Usage: " << prog << " [-n ] " << endl; exit(42); } int main(int argc, char * argv[]) { vector files[2]; int num_threads = 1; int file_to_read = 0; for (int i = 1; i < argc; i++) { if ( ! strcmp("-n", argv[i]) ) { if (i == argc - 1) usage(argv[0]); i++; num_threads = atoi(argv[i]); } else { if (file_to_read < 2) readFile(argv[i], files[file_to_read]); else usage(argv[0]); file_to_read++; } } if (file_to_read != 2) usage(argv[0]); pthread_t * threads = new pthread_t[num_threads]; int * similarityMatrix = new int[files[0].size() * files[1].size()]; pthread_barrier_init(&barrier, NULL, num_threads); for (int i = 0; i < num_threads; i++) { SMArg * arg = new SMArg; arg->s = &files[0]; arg->t = &files[1]; arg->id = i; arg->matrix = similarityMatrix; int ret = pthread_create(&threads[i], NULL, &calcSimMatrixThread, arg); if (ret) { cerr << "Error " << ret << " when creating thread!" << endl; return -4; } } for (int i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } pthread_barrier_destroy(&barrier); delete[] threads; return 0; } /* Read a file into a vector of non-space characters */ bool readFile(char * fileName, vector & v) { ifstream in(fileName); if (!in.is_open()) return false; while (!in.eof()) { char chr; in >> chr; v.push_back(chr); } return true; } /* Compute portions of the similarity matrix between two character arrays */ void * calcSimMatrixThread(void * arg) { SMArg * smarg = (SMArg *) arg; int s_size = smarg->s->size(); int t_size = smarg->t->size(); int (*F)[s_size][t_size] = (int (*) [s_size][t_size]) smarg->matrix; int max_x = 0, max_y = 0, max_val = 0; for (int i = 0; i < t_size; i++) /* set first row to 0's */ (*F)[0][i] = 0; for (int i = 0; i < s_size; i++) /* set first column to 0's */ (*F)[i][0] = 0; for (int i = 1; i < s_size; i++) { for (int j = 1; j < t_size; j++) { /* Compute the value for the matrix */ (*F)[i][j] = max( max( (*F)[i][j-1] - 2, (*F)[i-1][j-1] + (eq(smarg->s->at(i), smarg->t->at(j)) ? 1 : -1) ), max( (*F)[i-1][j] - 2, 0 ) ); /* See if we found a new maximum value */ if ((*F)[i][j] > max_val) { max_val = (*F)[i][j]; max_x = i; max_y = j; } else if ((*F)[i][j] == max_val) { /* If we found a value the same as our current maximum * value, see if it has a greater i+j value */ if ( (i + j) > (max_x + max_y) ) { max_x = i; max_y = j; } } } } cout << "Maximum value is " << max_val << " at position (" << max_x << ", " << max_y << ")" << endl; delete smarg; return NULL; }