fork download
  1. #include <string>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <vector>
  6. #include <cmath>
  7. #include <algorithm>
  8.  
  9. //defines
  10. #define space ' '
  11.  
  12. //disables any deprecation warning
  13. #pragma warning(disable : 4996)
  14.  
  15. //usings
  16. using std::vector;
  17. using std::string;
  18. using std::cout;
  19. using std::endl;
  20.  
  21. long double nabs(long double dub) {
  22. return -abs(dub);
  23. }
  24.  
  25. string remove_char(string str, char c = space) {
  26. str.erase(std::remove(str.begin(), str.end(), c), str.end());
  27. return str;
  28. }
  29.  
  30. long double parse(string str) {
  31. return std::stold(str);
  32. }
  33.  
  34. bool try_parse(string str) {
  35. char* end = 0;
  36. long double val = strtold(str.c_str(), &end);
  37. return end != str.c_str() && val != HUGE_VALL && val != -HUGE_VALL;
  38. }
  39.  
  40. char first_char(string str) {
  41. return *str.c_str();
  42. }
  43.  
  44. bool is_opr(string str) {
  45. return first_char(str) == '&';
  46. }
  47.  
  48. string &first_item(vector<string> vec) {
  49. return vec[0];
  50. }
  51.  
  52. vector<string> get_types(vector<string> vec) {
  53. for (int i = 0; i < vec.size(); i++) {
  54. string &s = vec[i];
  55. bool doubly = try_parse(s);
  56. bool amp = is_opr(s);
  57.  
  58. //if unknown
  59. if (!doubly && !amp) {
  60. s = "<unk> " + s;
  61. continue;
  62. }
  63. //if operator
  64. else if (!doubly && amp) {
  65. s = "<opr> " + s;
  66. continue;
  67. }
  68. //if number
  69. else if (doubly && !amp) {
  70. s = "<dub> " + s;
  71. continue;
  72. }
  73.  
  74. }
  75. return vec;
  76. }
  77.  
  78. long double interpretar_numero(string dub) {
  79. if (dub.substr(0, 6).compare("<dub> ") != 0) {
  80. throw "Não deu para interpretar como número " + dub;
  81. }
  82. return parse(dub.substr(6));
  83. }
  84.  
  85. long double get_result(vector<string> vec) {
  86. if (vec.at(0).compare("<opr> &sb") == 0 || vec.at(0).compare("<opr> &ad") == 0) {
  87. vec.insert(vec.begin(), "<dub> 0");
  88. }
  89. long double val = interpretar_numero(vec.at(0));
  90. for (int i = 1; i < vec.size(); i += 2) {
  91. std::string op = vec.at(i);
  92. if (vec.size() == i + 1) throw "Esperava um número antes do fim";
  93. long double ot = interpretar_numero(vec.at(i + 1));
  94.  
  95. if (op.compare("<opr> &ad") == 0) {
  96. val += ot;
  97. } else if (op.compare("<opr> &sb") == 0) {
  98. val -= ot;
  99. } else if (op.compare("<opr> &mp") == 0) {
  100. val *= ot;
  101. } else if (op.compare("<opr> &dv") == 0) {
  102. val /= ot;
  103. } else {
  104. throw "Esperava um operador";
  105. }
  106. }
  107. return val;
  108. }
  109.  
  110. vector<string> split(string s, const char c = space) {
  111. string buff{ "" };
  112. vector<string> v;
  113.  
  114. for (auto n : s) {
  115. if (n != c) {
  116. buff += n;
  117. } else if (n == c && buff != "") {
  118. v.push_back(buff);
  119. buff = "";
  120. }
  121. }
  122. if (buff != "") v.push_back(buff);
  123.  
  124. return v;
  125. }
  126.  
  127. string simplify(string expr) {
  128. string iexpr = expr;
  129. for (int i = 0; i < iexpr.length(); i++) {
  130.  
  131. char& c = iexpr[i];
  132.  
  133. if (c == '+') {
  134. iexpr.replace(i, 1, " &ad ");
  135. } else if (c == '-') {
  136. iexpr.replace(i, 1, " &sb ");
  137. } else if (c == '*') {
  138. iexpr.replace(i, 1, " &mp ");
  139. } else if (c == '/') {
  140. iexpr.replace(i, 1, " &dv ");
  141. }
  142. }
  143. return iexpr;
  144. }
  145.  
  146. int main() {
  147.  
  148. vector<string> sep_rep = get_types(split(simplify("-21 + 32 - 3 * 2")));
  149. for (auto str : sep_rep) {
  150. cout << str << endl;
  151. }
  152. try {
  153. cout << "R: " << get_result(sep_rep) << endl;
  154. } catch (const char *e) {
  155. cout << "Erro: " << e;
  156. } catch (string e) {
  157. cout << "Erro: " << e;
  158. }
  159.  
  160. std::cin.get();
  161. return 0;
  162. }
Success #stdin #stdout 0s 4540KB
stdin
Standard input is empty
stdout
<opr> &sb
<dub> 21
<opr> &ad
<dub> 32
<opr> &sb
<dub> 3
<opr> &mp
<dub> 2
R: 16