#include #include #include // for exit #include "CPstring.h" #include "vector.h" #include "ctimer.h" // for CTimer #include "strutils.h" // for StripPunc // author: Owen Astrachan // // lists all words in an input file, with word counts // uses class WordList to encapsulate behavior // // 5-15-95 struct WordStat { string info; // the string int count; // # of times string occurs WordStat * next; // pointer to next node in list }; class WordList { public: WordList(); // constructor ~WordList(); // destructor void Update(const string & word); // update occurrences of word int GetUnique(); // return # of unique words in list int GetTotal(); // return # of total words in list void Print(ostream & output); // print all words in list private: int myCount; // # of entries stored in myList int myTotal; // # of words (non-unique) WordStat * myList; // pointer to first node of list WordStat * Search(const string & key); // returns pointer }; WordList::WordList() : myCount(0), myTotal(0), myList(0) { // all work done in initializer list } WordList::~WordList() // postcondition: all new'd storage deleted { WordStat * current = myList; while (current != 0) { myList = myList->next; // advance to next delete current; // delete current (first) current = myList; // reset current } } WordStat * WordList::Search(const string & key) // postcondition: returns pointer to struct with key // returns 0 if key does not occur // performance: O(n), n = # items in myList { WordStat * current = myList; while (current != 0) { if (current->info == key) { return current; } current = current->next; } return 0; } void WordList::Update(const string & word) // postcondition: updates occurrence of word // adds word to list if not already present // otherwise updates count of # occurrences // increments count of total # of words { WordStat * loc = Search(word); myTotal++; if (loc != 0) { loc->count++; } else { myCount++; WordStat * wptr = new WordStat; // create new node wptr->info = word; // store values wptr->count = 1; // initialize all fields wptr->next = 0; if (myList == 0) // any nodes at all? { myList = wptr; } else if (word < myList->info) // goes in front? { wptr->next = myList; myList = wptr; } else { loc = myList; while (loc->next && loc->next->info < word) { loc = loc->next; } wptr->next = loc->next; loc->next = wptr; } } } void WordList::Print(ostream & output) // postcondition: all elements of list printed, sorted alphabetically { WordStat * current = myList; while (current != 0) { output << current->count << "\t" << current->info << endl; current = current->next; } output << endl << "# of words = " << myCount << endl; } int WordList::GetUnique() // postcondition: returns # unique words in list { return myCount; } int WordList::GetTotal() // postcondition: returns total # of words in list // same as # of times Update called { return myTotal; } int main() { string word; // word read from file string filename; // name of file ifstream input; WordList wlist; CTimer timer; double processTime; cout << "enter name of file: "; cin >> filename; input.open(filename); if (input.fail()) { cout << "could not open file " << filename << endl; exit(0); } while (input >> word) // reading word succeeded { word = word.Downcase(); StripPunc(word); timer.Start(); wlist.Update(word); timer.Stop(); } processTime = timer.CumulativeTime(); wlist.Print(cout); cout << "total words (non-unique): " << wlist.GetTotal() << endl; cout << "total time for update = " << processTime << endl; return 0; }