#include "WordTree.hpp" #include "rlutil.h" #include #include #include #include #include #include template 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 split(const std::string& s, char delim) { std::vector elems; split(s, delim, std::back_inserter(elems)); return elems; } class TypeAhead { std::string m_sentence; std::shared_ptr m_wordTree; public: TypeAhead() : m_sentence(""), m_wordTree(std::make_shared()) {} 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(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 words = split(m_sentence, ' '); std::string currentWord = words.back(); std::transform(currentWord.begin(), currentWord.end(), currentWord.begin(), ::tolower); std::vector 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; }