
C++ Programming Homework Solution on Matrix
- 19th Jan, 2022
- 23:40 PM
#include using namespace std; const int INF = 1000000000; // A very large number. // Store the file names in a vector. const vector file_names = vector({ "Wolves.csv", "Newcastle.csv", "Man_City.csv", "Leicester.csv", "Norwich.csv", "Crystal_Palace.csv", "Watford.csv", "Brighton.csv", "Spurs.csv", "Sheffield_Utd.csv", "West_Ham.csv", "Arsenal.csv", "Everton.csv", "Aston_Villa.csv", "Man_Utd.csv", "Bournemouth.csv", "Burnley.csv", "Chelsea.csv", "Liverpool.csv", "Southampton.csv", }); // Store the valid 20 team names in a vector. const vector team_names = vector({ "Leicester", "Wolves", "Everton", "Crystal Palace", "Man City", "Newcastle", "Arsenal", "Bournemouth", "Brighton", "Norwich", "Liverpool", "Watford", "Southampton", "Man Utd", "Spurs", "West Ham", "Aston Villa", "Sheffield Utd", "Burnley", "Chelsea", }); // class Match. Stores the names and the corresponding scores of each match. class Match{ public: Match(string name1, string name2, int score1, int score2) : name1(name1), name2(name2), score1(score1), score2(score2) {} string get_name1(){ return name1; } string get_name2(){ return name2; } int get_score1(){ return score1; } int get_score2(){ return score2; } private: string name1, name2; // `name1` represents Home Team, `name2` represents Away Team. int score1, score2; // `score1` represents score of Home Team, `score2` represents score of Away Team. }; // class Team. Stores the total matches of a team. class Team{ public: Team(){} vector get_matches(){ return matches; } void set_matches(Match& m){ matches.push_back(m); } private: vector matches; }; // Code to read a csv file and parse the inputs. string strip(string& s){ s = regex_replace(s, regex("^ +"), ""); s = regex_replace(s, regex(" +$"), ""); return s; } bool check(const string& s){ for(const auto e : team_names){ if(e == s) return true; } return false; } void read_csv(string file_name, Team& t){ fstream fin; fin.open(file_name, ios::in); vector row; string line, word, temp; bool flag = false; while(fin >> temp){ row.clear(); getline(fin, line); stringstream s(line); while(getline(s, word, '\t')){ row.push_back(strip(word)); } if(flag && row.size() == 6 && check(row[3]) && check(row[4])){ // Discarding inconsistent data. Some data is inconsistent because of misplaced tabs. if(row[5].find('-') != -1){ Match m(row[3], row[4], row[5][0]-'0', row[5][4]-'0'); // For played matches store the original score. t.set_matches(m); } else{ Match m(row[3], row[4], -1, -1); // For unplayed matches store -1 in the respective scores. t.set_matches(m); } } flag = true; } } // class EPL. Stores the total data of each and every team. class EPL{ public: EPL(){ for(const auto file_name : file_names){ Team t; string path = "Data/" + file_name; read_csv(path, t); teams.push_back(t); } } vector get_teams(){ return teams; } private: vector teams; }; // cout all team parameters. Just to check. void print(EPL& epl){ vector teams = epl.get_teams(); cout << "Total number of teams : " << teams.size() << endl; for(auto& team : teams){ vector matches = team.get_matches(); cout << "-----------------------------------------------------------\n"; cout << "Total matches for this team : " << matches.size() << endl; for(auto& match : matches){ cout << match.get_name1() << " " << match.get_name2() << " " << match.get_score1() << " " << match.get_score2() << endl; } cout << "-----------------------------------------------------------\n"; } } // The Matrix class. Stores the Home Team in the row index and the Away Team in the column index. // The corresponding index stores the score of Home Team - Away Team. // The matches which are not played are represented with INF. class Matrix{ public: Matrix(int size=20){ N = size; NNZ = 0; matrix.assign(N, vector(N, INF)); I.assign(N, 0); J.assign(N, 0); } int get_size(){ // Returns the size of the matrix. return N; } void set_ij(int i, int j, int s1, int s2){ assert(i < N && j < N); matrix[i][j] = s1-s2; if(s1 != s2) NNZ++; if(s1 > s2) I[i] += 1; else if (s1 < s2) J[j] += 1; } double get_ij(int i, int j){ assert(i < N && j < N); return matrix[i][j]; } void print_matrix(){ for(int i=0; i for(int j=0;j cout << matrix[i][j] << "\t"; } cout << endl; } } int get_I(int i){ return I[i]; } int get_J(int j){ return J[j]; } private: vector> matrix; vector I; // i'th element stores the number of times team i won in Home play. vector J; // i'th element stores the number of times team i won in Away play. int N; int NNZ; }; // Returns the index of the position of the team name in `team_names`. int index(string team_name){ for(int i=0; i if(team_names[i] == team_name) return i; } return -1; // This will not occur. Just for error checking. } template void printElement(T t, const int& width){ char separator = ' '; cout << left << setw(width) << setfill(separator) << t; } int main(){ EPL epl; //print(epl); Matrix matrix; // Fill the matrix. vector teams = epl.get_teams(); set> predict; //cout << "Total number of teams : " << teams.size() << endl; for(auto& team : teams){ vector matches = team.get_matches(); for(auto& match : matches){ const int i = index(match.get_name1()), j = index(match.get_name2()), s1 = match.get_score1(), s2 = match.get_score2(); if(s1 != -1 && s2 != -1) matrix.set_ij(i, j, s1, s2); else predict.insert({i, j}); } } //matrix.print_matrix(); vector count(20, 0); // Now predicting. cout << "Prediction Table : \n"; ofstream fout; fout.open("prediction.csv"); cout << "HOME TEAM\t\t\tAWAY TEAM\t\t\tPREDICTION\n"; fout << "HOME TEAM\tAWAY TEAM\tPREDICTION\n"; cout << "-----------------------------------------------------------------------------------------------------" << endl; for(const auto& p : predict){ int i = p.first, j = p.second; printElement(team_names[i], 32); printElement(team_names[j], 32); fout << team_names[i] << "\t" << team_names[j] << "\t"; int team1_h = matrix.get_I(i)/2, team1_a = matrix.get_J(i)/2, team2_h = matrix.get_I(j)/2, team2_a = matrix.get_J(j)/2; if(team1_h > team2_a){ cout << team_names[i] << " is predicted to win." << endl; fout << team_names[i] << " is predicted to win." << endl; count[i]++; } else if(team1_h < team2_a){ cout << team_names[j] << " is predicted to win." << endl; fout << team_names[j] << " is predicted to win." << endl; count[j]++; } else{ cout << "This match is predicted to be a draw." << endl; fout << "This match is predicted to be a draw." << endl; } cout << "-----------------------------------------------------------------------------------------------------" << endl; } fout.close(); vector> standing; for(int i=0; i<20; i++){ count[i] += (matrix.get_I(i) / 2) + (matrix.get_J(i) / 2); standing.push_back({-count[i], i}); } sort(standing.begin(), standing.end()); fout.open("standings.csv"); cout << "STANDINGS - " << endl; printElement("TEAM NAME : ", 32); printElement("WINS : ", 32); printElement("LOST / DRAW : ", 32); cout << endl; fout << "TEAM NAME\tWINS\tLOST / DRAW\n"; cout << "==============================================================================\n"; for(const auto& p : standing){ printElement(team_names[p.second], 32); printElement(to_string(-p.first), 32); printElement(to_string(38+p.first), 32); cout << endl; fout << team_names[p.second] << "\t" << -p.first << "\t" << 38+p.first << endl; } cout << "==============================================================================\n"; fout.close(); return 0; } // Run as : // $ g++ -std=c++17 -o main main.cpp // $ ./main // We can see in the output, in every instance where Liverpool is a Home Team it is expected to win.