/* src/dict_bsearch.cpp. This reads a dictionary of words from a file into a vector of strings. It sorts the vector, if not already sorted, and then it reads words from standard input It uses binary search to determine whether each of these words is in the dictionary. */ #include #include #include #include using namespace std; class Bsearch { public: void Create(const string &filename); // Create the vector from the file. bool Find(const string &word) const; // Return whether a word is in the vector. protected: vector words; }; /* Create() is straightforward -- it reads each words into a vector, and while doing so, determines whether the vector is sorted. If it is not, then it is sorted at the end of Create(). */ void Bsearch::Create(const string &filename) { ifstream fin; bool sorted; string w; sorted = true; fin.open(filename.c_str()); if (fin.fail()) throw (string) "Could not open " + filename; while (fin >> w) { if (words.size() > 0 && w < words[words.size()-1]) sorted = false; words.push_back(w); } if (!sorted) sort(words.begin(), words.end()); } /* Here's the binary search. It keeps track of three variables: l = the index of the smallest word that we are considering. h = the index of the largest word that we are considering. m = the middle of l and h It iterates by looking at words[m], and using that value to either return, discard the lower half of elements or discard the higher half of elements. */ bool Bsearch::Find(const string &word) const { int l, h, m; if (words.size() == 0) return false; l = 0; // Initially, we consider the entire vector h = words.size() - 1; while (l <= h) { m = (l + h) / 2; // printf("h-l:%d l:%d(%s) m:%d(%s) h:%d(%s)\n", h-l, // l, words[l].c_str(), m, words[m].c_str(), h, words[h].c_str()); if (words[m] == word) return true; if (words[m] > word) h = m-1; // Throw away the top half if (words[m] < word) l = m+1; // Throw away the bottom half } return false; } /* The main() is straightfoward -- create the dictionary from the file, then find each word on standard input. */ int main(int argc, char **argv) { Bsearch b; bool verbose, fnd; int tfound, total; string w; try { if (argc != 3) throw (string) "usage: a.out dictionary-file verbose(y/n) -- words on stdin."; verbose = (argv[2][0] == 'y'); tfound = 0; total = 0; b.Create(argv[1]); while (cin >> w) { total++; fnd = b.Find(w); if (fnd) tfound++; if (verbose) printf("%s: %s\n", w.c_str(), (fnd) ? "found" : "not-found"); } printf("Found: %d of %d\n", tfound, total); } catch (const string &s) { cerr << s << endl; return 1; } }