Advertisement
Toliak

AAAAAAAAA

Sep 27th, 2018
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.05 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. #define CALC_STATE_VARIABLE 4
  12.  
  13. #define CALC_PRIORITY_LENGTH 5
  14. #define CALC_PRIORITY_BRACKET 0
  15. #define CALC_PRIORITY_FUNCTION 1
  16. #define CALC_PRIORITY_UNARY 2
  17. #define CALC_PRIORITY_BINARY_0 3
  18. #define CALC_PRIORITY_BINARY_1 4
  19.  
  20. #define CALC_IS_COUNTABLE(x) ((x) == CALC_STATE_NUMBER || (x) == CALC_STATE_BRACKET || (x) == CALC_STATE_VARIABLE)
  21.  
  22. /*
  23.     CalculationElement: pair < element type , element value >
  24.     element types:
  25.         0: number
  26.         1: operation
  27.         2: bracket
  28.     element value:
  29.         1:
  30.             0: +
  31.             1: -
  32.             2: *
  33.             3: /
  34.             4: **
  35.  */
  36. typedef std::pair<unsigned char, long double> CalculationElement;
  37.  
  38. inline bool isCharLetter(char c) {
  39.     return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
  40. }
  41.  
  42. CalculationElement parseOperation(const std::string &operation) {
  43.     if (operation == "x") {             // Extra
  44.         return CalculationElement(CALC_STATE_VARIABLE, 0);
  45.     }
  46.  
  47.     static std::map<std::string, long double> operations;
  48.     operations["+"] = 0;
  49.     operations["-"] = 1;
  50.     operations["*"] = 2;
  51.     operations["/"] = 3;
  52.     operations["sin"] = 4;
  53.     operations["cos"] = 5;
  54.     operations["tg"] = 6;
  55.     operations["ctg"] = 7;
  56.     operations["exp"] = 8;
  57.  
  58.     std::map<std::string, long double>::iterator findIt = operations.find(operation);
  59.     if (findIt != operations.end())
  60.         return CalculationElement(CALC_STATE_OPERATION, findIt->second);
  61.  
  62.     // Check /[\-]+/ and /[\+]+/
  63.     /*
  64.     unsigned char addOperators = 255;
  65.     for (size_t i = 0; i < operation.size(); i++) {
  66.         if (operation[i] == '+') {
  67.             if (addOperators == 255) {
  68.                 addOperators = 0;
  69.             }
  70.         } else if (operation[i] == '-') {
  71.             if (addOperators == 255) {
  72.                 addOperators = 1;
  73.             } else {
  74.                 addOperators = (unsigned char)1 - addOperators;            // 1 -> 0; 0 -> 1
  75.             }
  76.         } else {
  77.             addOperators = 255;
  78.             break;
  79.         }
  80.     }
  81.     if (addOperators != 255)
  82.         return CalculationElement(CALC_STATE_OPERATION, addOperators);
  83.     */
  84.  
  85.     // Raise error
  86.     return CalculationElement(CALC_STATE_ERROR, 0);
  87. }
  88.  
  89. int parseLine(std::vector<std::vector<CalculationElement> > *elementsVector) {
  90.     char c;     // temp char
  91.     unsigned char state = 255;
  92.  
  93.     int numberPrecision = -1;
  94.     long double number = 0;
  95.  
  96.     std::string operation = "";
  97.     std::vector<size_t> bracketIds;
  98.     bracketIds.push_back(0);
  99.  
  100.     while (std::cin.get(c) && c != '\n') {
  101.         if (std::isspace(c)) continue;
  102.  
  103.         // Parse current char
  104.         if (c >= '0' && c <= '9') {
  105.             // Operation
  106.             if (state == CALC_STATE_OPERATION) {
  107.                 (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  108.                 operation = "";
  109.             }
  110.  
  111.             unsigned char numeral = (unsigned char) c - '0';     // always non-negative
  112.             if (numberPrecision == -1) {
  113.                 number = (number * 10 + numeral);
  114.             } else {
  115.                 number = number + numeral / powf(10.0, (float) numberPrecision);
  116.                 numberPrecision++;
  117.             }
  118.             state = CALC_STATE_NUMBER;
  119.         } else if (c == '.') {
  120.             if (numberPrecision == 1) {
  121.                 // Raise error
  122.             }
  123.             numberPrecision = 1;
  124.         } else {
  125.             if (state == CALC_STATE_NUMBER) {
  126.                 (*elementsVector)[*bracketIds.rbegin()].push_back(std::make_pair(state, number));
  127.                 number = 0;
  128.                 numberPrecision = -1;
  129.             }
  130.             switch (c) {
  131.                 case '(': {
  132.                     if (state == CALC_STATE_OPERATION) {
  133.                         (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  134.                         operation = "";
  135.                     }
  136.                     state = CALC_STATE_BRACKET;
  137.  
  138.                     size_t bracketId = *bracketIds.rbegin();            // Current braket
  139.                     size_t newBracketId = elementsVector->size();       // New bracket
  140.  
  141.                     (*elementsVector)[bracketId].push_back(std::make_pair(CALC_STATE_BRACKET, newBracketId));
  142.                     bracketIds.push_back(newBracketId);
  143.  
  144.                     std::vector<CalculationElement> tempVector;
  145.                     elementsVector->push_back(tempVector);
  146.                     break;
  147.                 }
  148.                 case ')':
  149.                     if (state == CALC_STATE_OPERATION) {
  150.                         (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  151.                         operation = "";
  152.                     }
  153.                     state = CALC_STATE_BRACKET;
  154.  
  155.                     bracketIds.pop_back();
  156.                     break;
  157.                 default:
  158.                     if (state != CALC_STATE_OPERATION && c == 'x') {
  159.                         // TODO: Add X
  160.                         state = CALC_STATE_VARIABLE;
  161.                         break;
  162.                     }
  163.                     if (state == CALC_STATE_OPERATION && (isCharLetter(*operation.rbegin()) != isCharLetter(c) || c == '+' || c == '-')) {
  164.                         (*elementsVector)[*bracketIds.rbegin()].push_back(parseOperation(operation));
  165.                         operation = "";
  166.                     }
  167.                     state = CALC_STATE_OPERATION;
  168.                     operation += c;
  169.                     break;
  170.             }
  171.         }
  172.     }
  173.  
  174.     // Handling last value
  175.     if (state == CALC_STATE_NUMBER) {
  176.         (*elementsVector)[*bracketIds.rbegin()].push_back(std::make_pair(state, number));
  177.     }
  178.     return 0;
  179. }
  180.  
  181. int calculateElements(std::vector<CalculationElement> *elements,
  182.                       std::vector<std::vector<CalculationElement> > *elementsVector) {
  183.  
  184.     if (elements->size() == 1) {
  185.         unsigned char state = elements->begin()->first;
  186.         if (state == CALC_STATE_NUMBER) {
  187.             return 0;
  188.         } else if (state == CALC_STATE_BRACKET) {
  189.             // pass
  190.         } else {
  191.             // Raise error
  192.         }
  193.     }
  194.  
  195.     /*
  196.      0: bracket
  197.      1: function call
  198.      2: unary operations
  199.      3: multiply, divide
  200.      4: +, -
  201.     */
  202.     // Priority setup
  203.     std::vector<std::vector<CalculationElement>::iterator> priorityQueues[CALC_PRIORITY_LENGTH];
  204.     for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  205.         switch (it->first) {
  206.             case CALC_STATE_OPERATION:
  207.                 if (it+1 == elements->end()) {
  208.                     // Raise error
  209.                 }
  210.  
  211.                 if (it == elements->begin()) {
  212.                     if (CALC_IS_COUNTABLE((it+1)->first) || ((it+1)->first == CALC_STATE_OPERATION && (it+1)->second >= 4)) {                                                      // it is unary operation
  213.                         if (it->second >= 4) {
  214.                             priorityQueues[CALC_PRIORITY_FUNCTION].push_back(it);
  215.                         } else {
  216.                             priorityQueues[CALC_PRIORITY_UNARY].push_back(it);
  217.                         }
  218.                     }
  219.                 } else {
  220.                     if (!CALC_IS_COUNTABLE((it-1)->first) && CALC_IS_COUNTABLE((it+1)->first)) {          // it is unary operation
  221.                         if (it->second >= 4) {
  222.                             priorityQueues[CALC_PRIORITY_FUNCTION].push_back(it);
  223.                         } else {
  224.                             priorityQueues[CALC_PRIORITY_UNARY].push_back(it);
  225.                         }
  226.                     } else if (CALC_IS_COUNTABLE((it-1)->first) && (CALC_IS_COUNTABLE((it+1)->first) || ((it+1)->first == CALC_STATE_OPERATION && (it+1)->second >= 4))) {           // binary operation
  227.                         if (it->second >= 4) {
  228.                             priorityQueues[CALC_PRIORITY_FUNCTION].push_back(it);
  229.                         } else if (it->second <= 3 && it->second >= 2) {
  230.                             priorityQueues[CALC_PRIORITY_BINARY_0].push_back(it);
  231.                         } else {
  232.                             priorityQueues[CALC_PRIORITY_BINARY_1].push_back(it);
  233.                         }
  234.                     } else {
  235.                         // Unexpected situation
  236.                         std::cout << "Unexpected operators (priority)" << std::endl;
  237.                     }
  238.                 }
  239.                 break;
  240.             case CALC_STATE_NUMBER:
  241.                 break;
  242.             case CALC_STATE_BRACKET:
  243.                 priorityQueues[CALC_PRIORITY_BRACKET].push_back(it);
  244.                 break;
  245.             case CALC_STATE_VARIABLE:
  246.                 // TODO: X
  247.                 break;
  248.             case CALC_STATE_ERROR:
  249.                 // Raise error
  250.                 break;
  251.         }
  252.     }
  253.  
  254.     for (std::vector<std::vector<CalculationElement>::iterator>::iterator it = priorityQueues[CALC_PRIORITY_BRACKET].begin(); it != priorityQueues[CALC_PRIORITY_BRACKET].end(); it++) {
  255.         std::vector<CalculationElement> bracket = (*elementsVector)[(*it)->second];
  256.         if (bracket.size() > 1 || (bracket.size() == 1 && bracket.begin()->first == CALC_STATE_BRACKET)) {
  257.             calculateElements(&bracket, elementsVector);
  258.         }
  259.         if (bracket.size() == 1 && bracket.begin()->first == CALC_STATE_NUMBER) {
  260.             (*it)->first = CALC_STATE_NUMBER;
  261.             (*it)->second = bracket.begin()->second;
  262.         } else {
  263.             // Raise error
  264.         }
  265.     }
  266.  
  267.     for (std::vector<std::vector<CalculationElement>::iterator>::iterator it = priorityQueues[CALC_PRIORITY_FUNCTION].begin(); it != priorityQueues[CALC_PRIORITY_FUNCTION].end(); it++) {
  268.         long double r;
  269.         if ((*it)->second == 4) {
  270.             r = sin((double)(*it + 1)->second);
  271.         } else {
  272.             r = -99;            // TODO: replace that sus
  273.         }
  274.  
  275.         elements->erase(*it, *it + 1);
  276.         (*it)->first = CALC_STATE_NUMBER;
  277.         (*it)->second = r;
  278.     }
  279.  
  280.     for (std::vector<std::vector<CalculationElement>::iterator>::iterator it = priorityQueues[CALC_PRIORITY_UNARY].begin(); it != priorityQueues[CALC_PRIORITY_UNARY].end(); it++) {
  281.         long double r = ((*it)->second == 1) ? (- (*it + 1)->second) : (*it + 1)->second;
  282.         elements->erase(*it, *it + 1);
  283.         (*it)->first = CALC_STATE_NUMBER;
  284.         (*it)->second = r;
  285.         (*it)--;
  286.     }
  287.  
  288.     for (std::vector<std::vector<CalculationElement>::iterator>::iterator it = priorityQueues[CALC_PRIORITY_BINARY_0].begin(); it != priorityQueues[CALC_PRIORITY_BINARY_0].end(); it++) {
  289.         std::vector<CalculationElement>::iterator it11 = (*it)-1;
  290.         std::vector<CalculationElement>::iterator it12 = (*it)+1;
  291.         long double r = ((*it)->second == 2) ? (((*it)-1)->second * ((*it)+1)->second) : (((*it)-1)->second / ((*it)+1)->second);
  292.         (*it)--;
  293.         elements->erase(*it, *it + 2);
  294.         (*it)->first = CALC_STATE_NUMBER;
  295.         (*it)->second = r;
  296.     }
  297.  
  298.     for (std::vector<std::vector<CalculationElement>::iterator>::iterator it = priorityQueues[CALC_PRIORITY_BINARY_1].begin(); it != priorityQueues[CALC_PRIORITY_BINARY_1].end(); it++) {
  299.         long double r = ((*it)->second == 0) ? (((*it)-1)->second + ((*it)+1)->second) : (((*it)-1)->second - ((*it)+1)->second);
  300.         (*it)--;
  301.         elements->erase(*it, *it + 2);
  302.         (*it)->first = CALC_STATE_NUMBER;
  303.         (*it)->second = r;
  304.     }
  305.  
  306.     /*
  307.         // Check brackets (and errors)
  308.         for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  309.             if (it->first == CALC_STATE_ERROR) {
  310.                 // Raise error
  311.                 // return 1;
  312.             }
  313.             if (it->first != CALC_STATE_BRACKET) continue;
  314.  
  315.             std::vector<CalculationElement> bracket = (*elementsVector)[it->second];
  316.             if (bracket.size() > 1 || (bracket.size() == 1 && bracket.begin()->first == CALC_STATE_BRACKET)) {
  317.                 calculateElements(&bracket, elementsVector);
  318.             } else if (bracket.size() == 1 && bracket.begin()->first == CALC_STATE_NUMBER) {
  319.                 it->first = CALC_STATE_NUMBER;
  320.                 it->second = bracket.begin()->second;
  321.             } else {
  322.                 // Raise error
  323.             }
  324.         }
  325.  
  326.         // Check unary operations
  327.  
  328.         // Check **
  329.         for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  330.             if (it->first != CALC_STATE_OPERATION) continue;
  331.             if (it->second != 4) continue;
  332.  
  333.             long double r = pow((double) (it - 1)->second, (double) (it + 1)->second);
  334.  
  335.             it--;
  336.             elements->erase(it, it + 2);
  337.             it->first = CALC_STATE_NUMBER;
  338.             it->second = r;
  339.         }
  340.  
  341.         // Check * and /
  342.         for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  343.             if (it->first != CALC_STATE_OPERATION) continue;
  344.             if (it->second != 2 && it->second != 3) continue;
  345.  
  346.             long double r;
  347.             switch ((int) it->second) {
  348.                 case 2:
  349.                     r = ((it - 1)->second * (it + 1)->second);
  350.                     break;
  351.                 case 3:
  352.                     r = ((it - 1)->second / (it + 1)->second);
  353.                     break;
  354.             }
  355.  
  356.             it--;
  357.             elements->erase(it, it + 2);
  358.             it->first = CALC_STATE_NUMBER;
  359.             it->second = r;
  360.         }
  361.  
  362.         // Check + and -
  363.         for (std::vector<CalculationElement>::iterator it = elements->begin(); it != elements->end(); it++) {
  364.             std::cout << "deb: " << (int)it->first << " " << it->second << std::endl;
  365.             if (it->first != CALC_STATE_OPERATION) continue;
  366.             if (it->second != 0 && it->second != 1) continue;
  367.  
  368.             if (it == elements->begin() || (it-1)->first != CALC_STATE_NUMBER) {
  369.                 // Unary operation
  370.                 if (it->second == 1) {
  371.                     long double r = - (it+1)->second;
  372.                     elements->erase(it, it + 1);
  373.                     it->first = CALC_STATE_NUMBER;
  374.                     it->second = r;
  375.  
  376.                     if (it != elements->begin()) {
  377.                         it -= 2;
  378.                     }
  379.                 }
  380.             } else if ((it+1)->first == CALC_STATE_OPERATION) {
  381.                 continue;
  382.             } else {
  383.                 // Binary operation
  384.                 long double r = (it->second == 0) ? ((it-1)->second + (it+1)->second) : ((it-1)->second - (it+1)->second);
  385.                 it--;
  386.                 elements->erase(it, it + 2);
  387.                 it->first = CALC_STATE_NUMBER;
  388.                 it->second = r;
  389.             }
  390.         }
  391.     */
  392.  
  393.     return 0;
  394. }
  395.  
  396. int main(const int argc, const char *argv[]) {
  397.     std::vector<int> v;
  398.     v.push_back(0);
  399.     v.push_back(1);
  400.     v.push_back(2);
  401.     v.push_back(3);
  402.     std::vector<int>::iterator it = v.begin() + 1;
  403.     std::cout << "deb: " << *it << std::endl;
  404.     v.erase(v.begin(), v.begin() + 1);
  405.     std::cout << "deb: " << *it << std::endl;
  406.  
  407.     std::vector<std::vector<CalculationElement> > elements;
  408.     std::vector<CalculationElement> element0;
  409.     elements.push_back(element0);
  410.     parseLine(&elements);
  411.  
  412.     for (std::vector<std::vector<CalculationElement> >::reverse_iterator it = elements.rbegin();
  413.          it != elements.rend(); it++) {
  414.         calculateElements(&*it, &elements);
  415.     }
  416.  
  417.     long double result = elements.begin()->begin()->second;
  418.     std::cout << "Result? " << result << std::endl;
  419. /*
  420.  
  421.  
  422.     for (std::vector<CalculationElement>::iterator it = elements.begin(); it != elements.end(); it++) {
  423.         std::cout << (int) it->first << " : " << it->second << std::endl;
  424.     }
  425.     */
  426.  
  427.     return 0;
  428. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement