Advertisement
Toliak

Untitled

Sep 26th, 2018
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.95 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <string>
  5. #include <map>
  6.  
  7. #define CALC_STATE_NUMBER 0
  8. #define CALC_STATE_OPERATION 1
  9. #define CALC_STATE_BRACKET 2
  10. #define CALC_STATE_ERROR 3
  11.  
  12. /*
  13. CalculationElement: pair < element type , element value >
  14. element types:
  15. 0: number
  16. 1: operation
  17. 2: bracket
  18. element value:
  19. 1:
  20. 0: +
  21. 1: -
  22. 2: *
  23. 3: /
  24. 4: **
  25. */
  26. typedef std::pair<unsigned char, long double> CalculationElement;
  27.  
  28. CalculationElement parseOperation(const std::string &operation) {
  29. static std::map<std::string, long double> operations;
  30. operations["+"] = 0;
  31. operations["-"] = 1;
  32. operations["*"] = 2;
  33. operations["/"] = 3;
  34. operations["**"] = 4;
  35. operations["pow"] = 4;
  36.  
  37. std::map<std::string, long double>::iterator findIt = operations.find(operation);
  38. if (findIt != operations.end())
  39. return CalculationElement(CALC_STATE_OPERATION, findIt->second);
  40.  
  41. // Raise error
  42. return CalculationElement(CALC_STATE_ERROR, 0);
  43. }
  44.  
  45. int parseLine(std::vector<std::vector<CalculationElement> > *elementsVector) {
  46. char c; // temp char
  47. unsigned char state = 255;
  48.  
  49. int numberPrecision = -1;
  50. long double number = 0;
  51.  
  52. std::string operation = "";
  53. std::vector<size_t> bracketIds;
  54. bracketIds.push_back(0);
  55.  
  56. while (std::cin.get(c) && c != '\n') {
  57. if (std::isspace(c)) continue;
  58.  
  59. // Parse current char
  60. if (c >= '0' && c <= '9') {
  61. // Operation
  62. if (state == CALC_STATE_OPERATION) {
  63. (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  64. operation = "";
  65. }
  66.  
  67. unsigned char numeral = (unsigned char) c - '0'; // always non-negative
  68. if (numberPrecision == -1) {
  69. number = (number * 10 + numeral);
  70. } else {
  71. number = number + numeral / powf(10.0, (float) numberPrecision);
  72. numberPrecision++;
  73. }
  74. state = CALC_STATE_NUMBER;
  75. } else if (c == '.') {
  76. if (numberPrecision == 1) {
  77. // Raise error
  78. }
  79. numberPrecision = 1;
  80. } else {
  81. if (state == CALC_STATE_NUMBER) {
  82. (*elementsVector)[*bracketIds.rbegin()].push_back(std::make_pair(state, number));
  83. number = 0;
  84. numberPrecision = -1;
  85. }
  86. switch (c) {
  87. case '(': {
  88. if (state == CALC_STATE_OPERATION) {
  89. (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  90. operation = "";
  91. }
  92. state = CALC_STATE_BRACKET;
  93.  
  94. size_t bracketId = *bracketIds.rbegin(); // Current braket
  95. size_t newBracketId = elementsVector->size(); // New bracket
  96.  
  97. (*elementsVector)[bracketId].push_back(std::make_pair(CALC_STATE_BRACKET, newBracketId));
  98. bracketIds.push_back(newBracketId);
  99.  
  100. std::vector<CalculationElement> tempVector;
  101. elementsVector->push_back(tempVector);
  102. break;
  103. }
  104. case ')':
  105. if (state == CALC_STATE_OPERATION) {
  106. (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  107. operation = "";
  108. }
  109. state = CALC_STATE_BRACKET;
  110.  
  111. bracketIds.pop_back();
  112. break;
  113. default:
  114. state = CALC_STATE_OPERATION;
  115. operation += c;
  116. break;
  117. }
  118. }
  119. }
  120.  
  121. // Handling last value
  122. if (state == CALC_STATE_NUMBER) {
  123. (*elementsVector)[*bracketIds.rbegin()].push_back(std::make_pair(state, number));
  124. }
  125. return 0;
  126. }
  127.  
  128. int calculateElements(std::vector<CalculationElement> *elements,
  129. std::vector<std::vector<CalculationElement> > *elementsVector) {
  130. if (elements->size() == 1) {
  131. unsigned char state = elements->begin()->first;
  132. if (state == CALC_STATE_NUMBER) {
  133. return 0;
  134. } else if (state == CALC_STATE_BRACKET) {
  135. // pass
  136. } else {
  137. // Raise error
  138. }
  139. }
  140.  
  141. // Check brackets (and errors)
  142. for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  143. if (it->first == CALC_STATE_ERROR) {
  144. // Raise error
  145. // return 1;
  146. }
  147. if (it->first != CALC_STATE_BRACKET) continue;
  148.  
  149. std::vector<CalculationElement> bracket = (*elementsVector)[it->second];
  150. if (bracket.size() > 1 || (bracket.size() == 1 && bracket.begin()->first == CALC_STATE_BRACKET)) {
  151. calculateElements(&bracket, elementsVector);
  152. } else if (bracket.size() == 1 && bracket.begin()->first == CALC_STATE_NUMBER) {
  153. it->first = CALC_STATE_NUMBER;
  154. it->second = bracket.begin()->second;
  155. } else {
  156. // Raise error
  157. }
  158. }
  159.  
  160. // Check unary operations
  161.  
  162. // Check ** and * and /
  163. for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  164. if (it->first != CALC_STATE_OPERATION) continue;
  165. if (it->second != 2 && it->second != 3 && it->second != 4) continue;
  166.  
  167. long double r;
  168. switch ((int) it->second) {
  169. case 2:
  170. r = ((it - 1)->second * (it + 1)->second);
  171. break;
  172. case 3:
  173. r = ((it - 1)->second / (it + 1)->second);
  174. break;
  175. case 4:
  176. r = pow((double) (it - 1)->second, (double) (it + 1)->second);
  177. break;
  178. }
  179.  
  180. it--;
  181. elements->erase(it, it + 2);
  182. it->first = CALC_STATE_NUMBER;
  183. it->second = r;
  184. }
  185.  
  186. // Check + and -
  187. for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  188. std::cout << "deb: " << (int)it->first << " " << it->second << std::endl;
  189. if (it->first != CALC_STATE_OPERATION) continue;
  190. if (it->second != 0 && it->second != 1) continue;
  191.  
  192. if (it == elements->begin() || (it-1)->first != CALC_STATE_NUMBER) {
  193. // Unary operation
  194. if (it->second == 1) {
  195. long double r = - (it+1)->second;
  196. elements->erase(it, it + 1);
  197. it->first = CALC_STATE_NUMBER;
  198. it->second = r;
  199.  
  200. if (it != elements->begin()) {
  201. it--;
  202. }
  203. }
  204. } else {
  205. // Binary operation
  206. long double r = (it->second == 0) ? ((it-1)->second + (it+1)->second) : ((it-1)->second - (it+1)->second);
  207. it--;
  208. elements->erase(it, it + 2);
  209. it->first = CALC_STATE_NUMBER;
  210. it->second = r;
  211. }
  212. }
  213.  
  214. return 0;
  215. }
  216.  
  217. int main(const int argc, const char *argv[]) {
  218. std::vector<std::vector<CalculationElement> > elements;
  219. std::vector<CalculationElement> element0;
  220. elements.push_back(element0);
  221. parseLine(&elements);
  222.  
  223. for (std::vector<std::vector<CalculationElement> >::reverse_iterator it = elements.rbegin();
  224. it != elements.rend(); it++) {
  225. calculateElements(&*it, &elements);
  226. }
  227.  
  228. long double result = elements.begin()->begin()->second;
  229. std::cout << "Result? " << result << std::endl;
  230. /*
  231.  
  232.  
  233. for (std::vector<CalculationElement>::iterator it = elements.begin(); it != elements.end(); it++) {
  234. std::cout << (int) it->first << " : " << it->second << std::endl;
  235. }
  236. */
  237.  
  238. return 0;
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement