diff options
Diffstat (limited to 'Homework/cs3460/typeahead/main.cpp')
| -rw-r--r-- | Homework/cs3460/typeahead/main.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/Homework/cs3460/typeahead/main.cpp b/Homework/cs3460/typeahead/main.cpp new file mode 100644 index 0000000..4c1a714 --- /dev/null +++ b/Homework/cs3460/typeahead/main.cpp @@ -0,0 +1,120 @@ +#include "WordTree.hpp"
+#include "rlutil.h"
+
+#include <algorithm>
+#include <fstream>
+#include <iterator>
+#include <memory>
+#include <sstream>
+#include <string>
+
+template <typename Out>
+void split(const std::string& s, char delim, Out result)
+{
+ std::istringstream iss(s);
+ std::string item;
+ while (std::getline(iss, item, delim))
+ {
+ *result++ = item;
+ }
+}
+
+std::vector<std::string> split(const std::string& s, char delim)
+{
+ std::vector<std::string> elems;
+ split(s, delim, std::back_inserter(elems));
+ return elems;
+}
+
+class TypeAhead
+{
+ std::string m_sentence;
+ std::shared_ptr<WordTree> m_wordTree;
+
+ public:
+ TypeAhead() :
+ m_sentence(""), m_wordTree(std::make_shared<WordTree>()) {}
+
+ void constructWordTreeFromFile(std::string filename)
+ {
+ std::ifstream inFile = std::ifstream(filename, std::ios::in);
+
+ while (!inFile.eof())
+ {
+ std::string word;
+ std::getline(inFile, word);
+ // Need to consume the carriage return character for some systems, if it exists
+ if (!word.empty() && word[word.size() - 1] == '\r')
+ {
+ word.erase(word.end() - 1);
+ }
+ // Keep only if everything is an alphabetic character -- Have to send isalpha an unsigned char or
+ // it will throw exception on negative values; e.g., characters with accent marks.
+ if (std::all_of(word.begin(), word.end(), [](unsigned char c)
+ { return std::isalpha(c); }))
+ {
+ std::transform(word.begin(), word.end(), word.begin(), [](char c)
+ { return static_cast<char>(std::tolower(c)); });
+ m_wordTree->add(word);
+ }
+ }
+ }
+
+ bool update()
+ {
+ char input = rlutil::getkey();
+
+ if (input == rlutil::KEY_ESCAPE)
+ return false;
+
+ if (input == rlutil::KEY_BACKSPACE)
+ {
+ if (m_sentence.length() > 0)
+ m_sentence.pop_back();
+ return true;
+ }
+
+ m_sentence += input;
+
+ return true;
+ }
+
+ void draw()
+ {
+ rlutil::cls();
+ std::uint32_t cursorY = m_sentence.size() / rlutil::tcols() + 1;
+ std::uint32_t cursorX = m_sentence.length() % rlutil::tcols();
+
+ std::cout << m_sentence << std::endl;
+
+ std::cout << " --- predictions ---" << std::endl;
+
+ if (m_sentence.size() > 0 && m_sentence.back() != ' ')
+ {
+ std::vector<std::string> words = split(m_sentence, ' ');
+ std::string currentWord = words.back();
+ std::transform(currentWord.begin(), currentWord.end(), currentWord.begin(), ::tolower);
+ std::vector<std::string> predictions = m_wordTree->predict(currentWord, rlutil::trows() - cursorY - 2);
+
+ for (std::string prediction : predictions)
+ std::cout << prediction << std::endl;
+ }
+
+ rlutil::locate(cursorX + 1, cursorY);
+ }
+};
+
+int main()
+{
+ rlutil::cls();
+
+ TypeAhead program;
+ program.constructWordTreeFromFile("dictionary.txt");
+
+ do
+ {
+ program.draw();
+ } while (program.update());
+
+ return 0;
+}
|
