Advertisement
AaronThomsen

Spell Check

May 19th, 2018
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <map>
  5. #include <utility>
  6. #include <fstream>
  7. #include <sstream>
  8. #include <algorithm>
  9.  
  10. using namespace std;
  11.  
  12. class BK{
  13. private:
  14.     struct Node{
  15.         string word;
  16.         map<int,Node*> children;
  17.         Node(string w) : word(w){}
  18.     };
  19.  
  20.     Node* root;
  21.     const int threshold = 2;
  22.  
  23.     int lev(string s1, string s2){
  24.         int m = static_cast<int>(s1.size()),
  25.             n = static_cast<int>(s2.size());
  26.         vector<vector<int>> c(n + 1, vector<int>(m + 1));
  27.         for(int i = 0; i <= m; i++) c[0][i] = i;
  28.         for(int i = 1; i <= n; i++) c[i][0] = i;
  29.         for(int i = 1,k; i <= n; i++){
  30.             for(int j = 1; j <= m; j++){
  31.                 k = c[i-1][j-1]+(s1[j-1]==s2[i-1]?0:1);
  32.                 c[i][j] = (c[i][j-1]<c[i-1][j]?c[i][j-1]:c[i-1][j])+1;
  33.                 c[i][j] = (c[i][j]<k)?c[i][j]:k;
  34.             }
  35.         }
  36.         return c[n][m];
  37.     }
  38.  
  39.     void clearNode(Node* root){
  40.         if(!root->children.empty())
  41.             for(auto i = root->children.begin(); i != root->children.end(); ++i) clearNode(i->second);
  42.         delete root;
  43.     }
  44.  
  45.     void insert(Node* root, string s){
  46.         int diff = lev(root->word, s);
  47.         if(root->children.count(diff))
  48.             insert(root->children[diff], s);
  49.         else
  50.             root->children.insert({diff, new Node(s)});
  51.     }
  52.  
  53.     void getSuggestion(Node* root, string s, vector<string>& v){
  54.         int diff = lev(root->word, s);
  55.         if(diff <= threshold)
  56.             v.push_back(root->word);
  57.         for(int i = diff-threshold; i <= diff+threshold; i++){
  58.             if(root->children.count(i))
  59.                 getSuggestion(root->children[i], s, v);
  60.         }
  61.     }
  62. public:
  63.     BK() : root(nullptr){}
  64.     ~BK(){
  65.         clearNode(root);
  66.     }
  67.  
  68.     void insert(string s){
  69.         if(!root)
  70.             root = new Node(s);
  71.         else
  72.             insert(root, s);
  73.     }
  74.  
  75.     vector<string> getSuggestion(string s){
  76.         vector<string> v;
  77.         getSuggestion(root, s, v);
  78.         return v;
  79.     }
  80. };
  81.  
  82. void populate(string fName, BK& b, vector<string>& v);
  83. void parseString(string s, BK& b, vector<string>& v);
  84. bool inDict(string s, vector<string>& v);
  85.  
  86. int main(){
  87.     vector<string> dictionary;
  88.     BK bkTree;
  89.     populate("words.txt", bkTree, dictionary);
  90.  
  91.     string s;
  92.  
  93.     while(true) {
  94.         cout << "\nEnter a string: ";
  95.         getline(cin, s);
  96.         parseString(s, bkTree, dictionary);
  97.     }
  98. }
  99.  
  100. void populate(string fName, BK& b, vector<string>& v){
  101.     ifstream in(fName);
  102.     string s;
  103.  
  104.     if(!in){
  105.         cerr << "Error opening file: " << fName;
  106.         throw string("Bad File");
  107.     }
  108.  
  109.     cout << "Now populating dictionary and BK-Tree..." << endl;
  110.     while(getline(in, s)){
  111.         transform(s.begin(), s.end(), s.begin(), ::tolower);
  112.         v.push_back(s);
  113.         b.insert(s);
  114.     }
  115.     cout << "Finished!" << endl;
  116. }
  117.  
  118. void parseString(string s, BK& b, vector<string>& v){
  119.     transform(s.begin(), s.end(), s.begin(), ::tolower);
  120.     stringstream ss(s); //snake
  121.     vector<string> suggestions;
  122.  
  123.     while(getline(ss, s, ' ')){
  124.         if(!inDict(s,v)){
  125.             suggestions = b.getSuggestion(s);
  126.             cout << "Misspelled word: " << s << endl;
  127.             cout << "Suggestions: ";
  128.             for(auto i = suggestions.begin(); i != suggestions.end(); ++i)
  129.                 cout << *i << " ";
  130.             cout << endl << endl;
  131.         }
  132.     }
  133. }
  134.  
  135. bool inDict(string s, vector<string>& v){
  136.     int l = 0, h = static_cast<int>(v.size())-1, m;
  137.     while(l <= h){
  138.         m = (l + h) / 2;
  139.         if(v[m] > s)
  140.             h = m - 1;
  141.         else if(v[m] < s)
  142.             l = m + 1;
  143.         else
  144.             return true;
  145.     }
  146.     return false;
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement