/* CS 377 Home work 1 Matthew Harrison 20982469 <mharriso@student.umass.edu> So, as always, I procrastinated. And as always, there are bugs. Many. You'll notice that my sets are horribly broken - it only records one instance of a word in a file. Also, this is way longer than it needs to be and is rather a mess in places. Next time, I'll start earlier.*/#include <iostream>#include <fstream>#include <string>#include <map>#include <set>#include <iterator>#include <vector>//set this to true if you want to see my debugging output#define DEBUG trueusing namespace std;void debug(string d) { if(DEBUG) { cout << d << endl; }}/*================================================================================Begin class inverter================================================================================*/class inverter { private: map<string, set<int> > invertedIndex; public: inverter(); ~inverter(); void insertWord(string, int); void printIndex(); void printSet(set<int>&);};inverter::inverter() { debug("New inverter created.");}inverter::~inverter() {}/*search invertedIndex for the word. If it exists, add the file # it came from into the set. If it doesn't exist, add it to the map.*/void inverter::insertWord(string word, int fileIndex) { set<int> s; s.insert(fileIndex); this->invertedIndex.insert(make_pair(word, s)); //here's where I *tried* to fix my sets //map<string, set<int> >::iterator mi = this->invertedIndex.find(word); //set<int> si = mi->second;}/* This cycles through my invertedIndex and prints it out as per the instructions. Notice the lack of proper set functionality.*/void inverter::printIndex() { map<string, set<int> >::iterator it; for(it = this->invertedIndex.begin(); it != this->invertedIndex.end(); ++it) { cout << it->first << ":"; printSet(it->second); cout << endl; }}//Print out a given set, called from printIndex()void inverter::printSet(set<int> &s) { set<int>::iterator it; for(it = s.begin(); it != s.end(); ++it) { cout << *it << " "; }}/*================================================================================End class inverter================================================================================*//*================================================================================Begin class files================================================================================*/class fileParser { private: map<int, string> fileList;//this turned out to be useless int fileCounter; public: fileParser(); ~fileParser(); void loadFiles(string&); void parseFile(string&, int, inverter&); void tokenize(string, int, inverter&);};fileParser::fileParser() { this->fileCounter = 0;}fileParser::~fileParser() {}//Open the file passed to main() and populate fileList with the files thereinvoid fileParser::loadFiles(string &flist) { ifstream f; f.open(flist.c_str()); debug("Reading from file: " + flist); char ch; string curFileName; inverter inv; if(!f.good()) { cout << "Error: Input file not valid." << endl; exit(-1); } while(!f.eof()) { f.get(ch); if(ch != '\n') { curFileName += ch; } else { if(curFileName.size()) { //a bit of a kludge to ignore blank lines this->fileList[fileCounter] = curFileName; debug("Found file: " + curFileName); //parse the current file here parseFile(curFileName, this->fileCounter, inv); this->fileCounter++; curFileName.clear(); } } } f.close(); inv.printIndex();//display the output once all files have been parsed}/* This reads in fileName, then sends each line to tokenize()*/void fileParser::parseFile(string &fileName, int findex, inverter &inv) { ifstream f; f.open(fileName.c_str()); char ch; string s; while(!f.eof()) { f.get(ch); //strip these because I'm too lame to understand strtok() if((ch != '\n') && (ch != '.') && (ch != '?') && (ch != '!') && (ch != ',') && (ch != '#') && (ch != '@')) { s += ch; } else { if(s.size()) { debug("Tokenizing: " + s); tokenize(s, findex, inv); s.clear(); } } } f.close();}/* This just splits up words based on spaces and adds them to the invertedIndex.*/void fileParser::tokenize(string s, int findex, inverter &inv) { char *tok = const_cast<char*>(s.c_str());//OMG HAX char *result = strtok(tok, " "); while(result != NULL) { inv.insertWord(result, findex); result = strtok(NULL, " "); }}/*================================================================================End class files================================================================================*/void test(string fname) { //method for debugging fileParser f; f.loadFiles(fname);}int main(int argc, char* argv[]) { if (argc < 2) { cout << "Error: Must provide an input file." << endl; exit(-1); } test(argv[1]); return 0;}