home/C++

C++

Contents:
╘>Matrix operations
    ╘>matrix.h
    ╘>matrix.cpp
    ╘>Test data
╘>Document retrieval using keywords
    ╘>DocRetrieval.cpp
    ╘>Test data
╘>Movie review collector
    ╘>Movies.cpp
    ╘>Test data

back to top
Matrix operations
/* FILE: matrix.h Name: Luke O'Callaghan */ #ifndef _matrix_H_ #define _matrix_H_ #include <iostream> using namespace std; const int MAX_ROW = 5; const int MAX_COLUMN = 5; //******************************************** // Matrix class definition. template <class T> class matrix; template <class T> ostream& operator<<(ostream &, const matrix<T> &); template <class T> istream& operator>>(istream &, matrix<T> &); template <class T> class matrix { friend ostream& operator<< <T>(ostream &, const matrix<T> &); friend istream& operator>> <T>(istream &, matrix<T> &); private: int column; int row; T data[MAX_ROW][MAX_COLUMN]; public: matrix(); matrix(const int &, const int &); matrix<T> operator+(const matrix<T> &); matrix<T> operator-(const matrix<T> &); matrix<T> operator*(const matrix<T> &); }; //******************************************** // Complex matrix class definition class complexn; ostream& operator<<(ostream &, const complexn &); istream& operator>>(istream &, complexn &); class complexn { friend ostream& operator<<(ostream &, const complexn &); friend istream& operator>>(istream &, complexn &); private: float real; float img; float g; public: complexn(); complexn(const float &, const float &); complexn operator+(const complexn &); complexn operator-(const complexn &); complexn operator*(const complexn &); void operator=(const int &); // Used to initialise the complexn type matrix }; #endif

/* FILE: matrix.cpp Name: Luke O'Callaghan */ #include <iostream> #include <iomanip> #include <cmath> #include <typeinfo> #include "matrix.h" using namespace std; //************************************ // Global manipulator flags bool info_flag = false; bool cplx_flag = true; // default value bool real_flag = false; bool img_flag = false; bool magnitude_flag = false; //************************************ // matrix manipulators ostream& info(ostream &out) { info_flag = true; return out; } ostream& noinfo(ostream &out) { info_flag = false; return out; }; //************************************ // matrix function implementations template <class T> ostream& operator<<(ostream &out, const matrix<T> &m) { if(info_flag == true) cout << m.row << "x" << m.column << " matrix" << endl; for(int i = 0; i < m.row; ++i) { for(int j = 0; j < m.column; ++j) { out << '\t' << fixed << setprecision(1) << m.data[i][j]; } out << endl; } return out; } template <class T> istream& operator>>(istream &in, matrix<T> &m) { for(int i = 0; i < m.row; ++i) { for(int j = 0; j < m.column; ++j) { in >> m.data[i][j]; } } return in; } template <class T> matrix<T>::matrix() { row = 0; column = 0; } template <class T> matrix<T>::matrix(const int &new_row, const int &new_column) { row = new_row; column = new_column; for(int i = 0; i < row; ++i){ for(int j = 0; j < column; ++j){ data[i][j] = 0; } } } template <class T> matrix<T> matrix<T>::operator+(const matrix<T> &b) { if(row != b.row || column != b.column) throw(string("Matrices are not the same size.")); if(typeid(*this).name() != typeid(b).name())// NOTE: not able to compile if types are different. throw(string("Matrix types are not the same.")); matrix<T> c(row, column); for(int i = 0; i < row; ++i){ for(int j = 0; j < column; ++j){ c.data[i][j] = data[i][j] + b.data[i][j]; } } return c; } template <class T> matrix<T> matrix<T>::operator-(const matrix<T> &b) { if(row != b.row || column != b.column) throw(string("Matrices are not the same size.")); if(typeid(*this).name() != typeid(b).name())// NOTE: not able to compile if types are different. throw(string("Matrix types are not the same.")); matrix<T> c(row, column); for(int i = 0; i < row; ++i){ for(int j = 0; j < column; ++j){ c.data[i][j] = data[i][j] - b.data[i][j]; } } return c; } template <class T> matrix<T> matrix<T>::operator*(const matrix<T> &b) { if(row != b.column && b.row != column) throw(string("Matrices are not the same size.")); if(typeid(*this).name() != typeid(b).name()) // NOTE: not able to compile if types are different. throw(string("Matrix types are not the same.")); matrix<T> c(row, b.column); for(int i = 0; i < row; ++i){ for(int j = 0; j < b.column; ++j){ c.data[i][j] = 0; for(int k = 0; k < column; ++k){ c.data[i][j] = c.data[i][j] + data[i][k] * b.data[k][j]; } } } return c; } //*********************************************** // complexn manipulators // flags defined at the begining of file matrix.cpp ostream& cplx(ostream& out) { cplx_flag = true; real_flag = false; img_flag = false; magnitude_flag = false; return out; } ostream& real(ostream& out) { cplx_flag = false; real_flag = true; img_flag = false; magnitude_flag = false; return out; } ostream& img(ostream& out) { cplx_flag = false; real_flag = false; img_flag = true; magnitude_flag = false; return out; } ostream& magnitude(ostream& out) { cplx_flag = false; real_flag = false; img_flag = false; magnitude_flag = true; return out; } //*********************************************** // complexn function implementations ostream& operator<<(ostream &out, const complexn &complex) { if(cplx_flag == true){ out << fixed << setprecision(1) << complex.real; switch ((int)complex.img){ case 0: cout << showpos << complex.img << "i" << noshowpos; break; case 1: cout << "+i"; break; default: cout << showpos << complex.img << "i" << noshowpos; } } if(real_flag == true){ out << fixed << setprecision(1) << complex.real; } if(img_flag == true){ switch ((int)complex.img){ case 0: cout << showpos << complex.img << "i" << noshowpos; break; case 1: cout << "i"; break; default: cout << complex.img << "i"; } } if(magnitude_flag == true){ cout << complex.g; } return out; } istream& operator>>(istream &in, complexn &complex) { in >> complex.real >> complex.img; return in; } complexn::complexn() { real = 0; img = 0; g = 0;// g means magnitude } complexn::complexn(const float &new_real, const float &new_img) { real = new_real; img = new_img; g = sqrt((real * real) + (img * img)); } complexn complexn::operator+(const complexn &b) { float new_real = 0; float new_img = 0; new_real = real + b.real; new_img = img + b.img; complexn c(new_real, new_img);// call the constructor to make the new object and calculate the magnitude return c; } complexn complexn::operator-(const complexn &b) { float new_real = 0; float new_img = 0; new_real = real - b.real; new_img = img - b.img; complexn c(new_real, new_img);// call the constructor to make the new object and calculate the magnitude return c; } complexn complexn::operator*(const complexn &b) { float new_real = 0; float new_img = 0; new_real = (real * b.real) - (img * b.img); new_img = (img * b.real) + (real * b.img); complexn c(new_real, new_img); // call the constructor to make the new object and calculate the magnitude return c; } // NOTE: must be included so that matrix constructor can intialise the memory to zero. void complexn::operator=(const int &a) { real = (float)a; img = (float)0; }

Test data:

3 3 1.3 2.5 3.8 4.2 5.4 6.8 7.7 8.5 9.1 3 3 4.6 5.4 6.3 7.8 8.5 9.1 1.9 2.6 3.4 3 3 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 3 3 5 6 6 7 7 8 9 4 7 4 1 2 2 3 3 4 4 5

back to top
Document retrieval using keywords
/* FILE: DocRetrieval.cpp Name: Luke O'Callaghan Description: Search files listed in the file "listofdocs.txt". Returns a list of the documents with relevance in descending order. Requirements: Must be a text file. Usage: ./search [keywords] */ #include <iostream> #include <iomanip> #include <cmath> #include <fstream> #include <vector> #include <map> #include <string> #include <algorithm> #include <functional> using namespace std; // Additional functions for the main program void load_keywords(vector<string> &, char**, int); void load_word_list(vector<string> &, vector<string> &, ifstream &); int count_similar(vector<string> , vector<string> ); void print_file(ifstream &); int main(int argc, char **argv) { ifstream docs("listofdocs.txt"); // load the list of documents into the program. ifstream fin; vector<string> keywords; vector<string> word_list; vector<string> original_text; multimap<double, string, greater<double> > results; // sort the relevance in descending order. string filename; int intersections = 0; double relevance = 0; if(!docs.good()) { cerr << "Error: listofdocs.txt does not exist!" << endl; return -1; } load_keywords(keywords, argv, argc); while(docs.good()) { docs >> filename; if(docs.eof()) // check if eof was triggered by the input function continue; // load the words into the word list. fin.open(filename.c_str()); if(!fin.good()) { // If the file can't be read, print error and continue the loop. cerr << "Error: cannot read " << filename << endl; continue; } load_word_list(word_list, original_text, fin); // save the original text for the calculation of the relevance later. // calculate the relevance of the keywords to the current document. intersections = count_similar(keywords, word_list); relevance = intersections / (sqrt(keywords.size()) * sqrt(original_text.size())); results.insert(pair<double, string>(relevance, filename)); // Clear the word list, original text, close the file and loop again. word_list.clear(); original_text.clear(); fin.close(); } docs.close(); // print the files in descending order. note: Map automatically sorts itself. multimap<double, string>::iterator it = results.begin(); for(int i = 0; i < results.size(); ++i) { cout << "(" << it->second << " - " << fixed << setprecision(2) << it->first * 100 << "%) "; fin.open(it->second.c_str()); print_file(fin); fin.close(); ++it; } return 0; } void load_keywords(vector<string> &keywords, char **inputs, int size) { string text, text_nopunct; for(int i = 1; i < size; ++i) { text = inputs[i]; // Remove punctuation and convert string to lowercase remove_copy_if(text.begin(), text.end(), back_inserter(text_nopunct), ptr_fun<int, int>(&ispunct)); transform(text_nopunct.begin(), text_nopunct.end(), text_nopunct.begin(), ::tolower); if(count(keywords.begin(), keywords.end(), text_nopunct) == 0) // If the word isn't in the vector, add it. otherwise ignore it. keywords.push_back(text_nopunct); text_nopunct = ""; // reset the string for next loop. } } void load_word_list(vector<string> &word_list, vector<string> &original_text, ifstream &fin) { string text, text_nopunct; while(fin.good()) { fin >> text; if(fin.eof()) // if there are no more words to read, exit the loop. continue; // Remove punctuation and convert string to lowercase remove_copy_if(text.begin(), text.end(), back_inserter(text_nopunct), ptr_fun<int, int>(&ispunct)); transform(text_nopunct.begin(), text_nopunct.end(), text_nopunct.begin(), ::tolower); if(count(word_list.begin(), word_list.end(), text_nopunct) == 0) // If the word isn't in the vector, add it. otherwise ignore it. word_list.push_back(text_nopunct); original_text.push_back(text); text_nopunct = ""; // reset the string for next loop. } } int count_similar(vector<string> keywords, vector<string> word_list) { vector<string>::iterator it = keywords.begin(); int intersect = 0; // count how many similar words contained in BOTH vectors. while(it != keywords.end()) { if(count(word_list.begin(), word_list.end(), *it)) // value > 0 is true, so if it does have the word then it will be true. ++intersect; ++it; } return intersect; } void print_file(ifstream &fin) { string text; int i = 0; for(i = 0; i < 10; ++i) { fin >> text; if(fin.eof()) // while reading, if the file gets to the end, exit the loop break; cout << text << ' '; } if(i == 10) // If it printed out 10 words, output "..." cout << "..." << endl; }

Test data:

(listofdocs.txt)

Kyle01.txt

(Kyle01.txt)

The Ten Network has dumped embattled host Kyle Sandilands as a judge on Australian Idol. Ten confirmed the news this afternoon, after its senior executives spent the weekend deliberating Sandilands' future.

back to top
Movie review collector
/* FILE: Movies.cpp Name: Luke O'Callaghan Description: Collects movie reviews and calculates the average of them. Requirements: File must have the format: number of reviews movie title score . . . Usage: ./movies [files] */ #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <map> #include <algorithm> using namespace std; int main(int argc, char **argv) { map<string, float> movie_rating; map<string, float> movie_amount; map<string, float>::iterator mr; map<string, float>::iterator ma; ifstream fin; string movie = ""; float rating = 0; int record_numbers = 0; for(int i = 1; i < argc; ++i) { fin.open(argv[i]); if(!fin.good()) { // If the file can't be read, print error and continue the loop. cerr << "Error: cannot read " << argv[i] << endl; continue; } fin >> record_numbers; fin.ignore(2, '\n'); // ignore newline character and carriage return if it exists. (DOS format only) for(int j = 0; j < record_numbers; ++j) { getline(fin, movie, '\n'); // Remove the carriage return from the input if it exists. (DOS format only) string::const_iterator s_it = movie.end() - 1; if(*s_it == '\r') { movie = movie.substr(0, movie.length() - 1); } fin >> rating; fin.ignore(2, '\n'); // ignore newline character and carriage return if it exists. (DOS format only) mr = movie_rating.find(movie); ma = movie_amount.find(movie); if(mr != movie_rating.end()) { // Increment the rating and the number of appearances. mr->second += rating; ma->second += 1; } else { // If it doesn't exist, add it to the map. movie_rating.insert(pair<string, float>(movie, rating)); movie_amount.insert(pair<string, float>(movie, 1)); } } fin.close(); } // Print out the movie ratings and their average rating. mr = movie_rating.begin(); ma = movie_amount.begin(); for(int i = 0; i < movie_rating.size(); ++i) { cout << mr->first << ": " << ma->second; if(ma->second > 1) // use plural if more than one review, else use singluar. cout << " reviews, average of "; else cout << " review, average of "; cout << setprecision(2) << mr->second / ma->second << "/5"<< endl; ++mr; ++ma; } return 0; }

Test data:

(ratings.txt)

7 Harry Potter and the Order of the Phoenix 4 Harry Potter and the Order of the Phoenix 5 The Bourne Ultimatum 3 Harry Potter and the Order of the Phoenix 4 The Bourne Ultimatum 4 Wall-E 4 Glitter 1

back to top