Technical test for a job interview.
at main 131 lines 3.9 kB view raw
1#include <iostream> 2#include "numeral_manager.hpp" 3 4bool NumeralManager::add(std::string word, int value, bool exclusive) 5{ 6 bool success = false; 7 if (exclusive) 8 { 9 success = _numeral_exclusive.insert(word); 10 } 11 else 12 { 13 success = _context_dependent.insert(word); 14 } 15 16 _values[word] = value; 17 return success; 18} 19 20bool NumeralManager::add(std::string word, NumeralModifier::Join joiner, bool exclusive) 21{ 22 bool success = false; 23 if (exclusive) 24 { 25 success = _numeral_exclusive.insert(word); 26 } 27 else 28 { 29 success = _context_dependent.insert(word); 30 } 31 32 _modifiers[word] = joiner; 33 return success; 34} 35 36bool NumeralManager::isNumeralWord(std::string word) 37{ 38 bool exclusive_find = _numeral_exclusive.search(word); 39 40 return exclusive_find || (_numeral_context && _context_dependent.search(word)); 41} 42 43NumeralWord *NumeralManager::analyze_numeral(std::string &text, int &pos, bool &alnum_state, bool &is_alnum, int &last_val) 44{ 45 std::string word = ""; 46 NumeralWord *numeral = nullptr; 47 int val = last_val; 48 int old_pos = pos; 49 alnum_state = std::isalnum(text[pos]); 50 is_alnum = std::isalnum(text[pos]); 51 52 while (pos < text.length()) 53 { 54 word = ""; 55 56 while (pos < text.length() && is_alnum == alnum_state) 57 { 58 word += text[pos]; 59 pos++; 60 is_alnum = std::isalnum(text[pos]); 61 } 62 63 if (alnum_state == true && !word.empty()) 64 { 65 // If we have read an alphanumeric chunk of characters 66 if (_modifiers.find(word) != _modifiers.end()) 67 { 68 if (numeral == nullptr) 69 { 70 numeral = new NumeralModifier(word, _modifiers[word]); 71 } 72 else 73 { 74 NumeralModifier *mod = new NumeralModifier(word, numeral, _modifiers[word]); 75 NumeralWord *next_numeral = analyze_numeral(text, pos, alnum_state, is_alnum, val); 76 mod->setChild(next_numeral); 77 78 numeral = mod; 79 } 80 } 81 else if (_values.find(word) != _values.end()) 82 { 83 val = _values[word]; 84 85 if (numeral == nullptr) 86 { 87 numeral = new NumeralNumber(word, val); 88 } 89 else if (val >= last_val) 90 { 91 // Assumes eurocentric property where bigger values 92 // following smaller values is a multiplication 93 // (like in "two hundred") 94 NumeralNumber *num = new NumeralNumber(word, val); 95 numeral->setChild(num); 96 } 97 else 98 { 99 // Assumes eurocentric property where smaller values 100 // following bigger values is a sum (like in "forty two") 101 NumeralModifier *mod = new NumeralModifier("+", numeral, NumeralModifier::ADD); 102 103 NumeralWord *next_numeral = analyze_numeral(text, old_pos, alnum_state, is_alnum, val); 104 pos = old_pos; 105 mod->setChild(next_numeral); 106 107 numeral = mod; 108 } 109 110 last_val = val; 111 } 112 } 113 114 old_pos = pos; 115 116 alnum_state = std::isalnum(text[pos]); 117 } 118 119 return numeral; 120} 121 122NumeralWord *NumeralManager::analyze(std::string &text) 123{ // We assume that this is called on a text that we already know is entirely a numeral 124 std::string word = ""; 125 int pos = 0; 126 bool alnum_state = std::isalnum(text[pos]); 127 bool is_alnum = std::isalnum(text[pos]); 128 int last_val = 0; 129 130 return analyze_numeral(text, pos, alnum_state, is_alnum, last_val); 131}