/* CS 377 Home work 1 Matthew Harrison 20982469 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 #include #include #include #include #include #include //set this to true if you want to see my debugging output #define DEBUG true using namespace std; void debug(string d) { if(DEBUG) { cout << d << endl; } } /* ================================================================================ Begin class inverter ================================================================================ */ class inverter { private: map > invertedIndex; public: inverter(); ~inverter(); void insertWord(string, int); void printIndex(); void printSet(set&); }; 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 s; s.insert(fileIndex); this->invertedIndex.insert(make_pair(word, s)); //here's where I *tried* to fix my sets //map >::iterator mi = this->invertedIndex.find(word); //set 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 >::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 &s) { set::iterator it; for(it = s.begin(); it != s.end(); ++it) { cout << *it << " "; } } /* ================================================================================ End class inverter ================================================================================ */ /* ================================================================================ Begin class files ================================================================================ */ class fileParser { private: map 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 therein void 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(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; }