Advertisement
stirante

Untitled

Jan 16th, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.84 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4.  
  5. using namespace std;
  6.  
  7. class CharElement {
  8. public:
  9.     CharElement* next;
  10.     char value;
  11.     CharElement(char value) {
  12.         this->value = value;
  13.         next = 0;
  14.     }
  15. };
  16. class LongElement {
  17. public:
  18.     LongElement* next;
  19.     long long value;
  20.     LongElement(long long value) {
  21.         this->value = value;
  22.         next = 0;
  23.     }
  24. };
  25. class StringElement {
  26. public:
  27.     StringElement* next;
  28.     string value;
  29.     StringElement(string value) {
  30.         this->value = value;
  31.         next = 0;
  32.     }
  33. };
  34. class Entry {
  35. public:
  36.     Entry* next;
  37.     int key;
  38.     string value;
  39. };
  40.  
  41. class Map {
  42. public:
  43.     Entry* first;
  44.     Entry* last;
  45.     Map() {
  46.         first = 0;
  47.         last = 0;
  48.     }
  49.     ~Map() {
  50.         while (!isEmpty()) {
  51.             remove(first->key);
  52.         }
  53.     }
  54.     void put(int key, string value) {
  55.         Entry* e = get(key);
  56.         if (e == 0) {
  57.             e = new Entry();
  58.             e->key = key;
  59.             e->value = value;
  60.             if (first == 0) {
  61.                 first = e;
  62.             } else {
  63.                 last->next = e;
  64.             }
  65.             last = e;
  66.         } else {
  67.             e->value = value;
  68.         }
  69.     }
  70.     Entry* get(int key) {
  71.         Entry* e = first;
  72.         while (e != 0) {
  73.             if (e->key == key) return e;
  74.             e = e->next;
  75.         }
  76.         return 0;
  77.     }
  78.     void remove(int key) {
  79.         Entry* e = first;
  80.         if (e != 0 && e->key == key) {
  81.             first = e->next;
  82.             delete e;
  83.         }
  84.         else {
  85.             while (e != 0) {
  86.                 if (e->next != 0 && e->next->key == key) {
  87.                     Entry* del = e->next;
  88.                     e->next = del->next;
  89.                     delete del;
  90.                     break;
  91.                 }
  92.             }
  93.         }
  94.     }
  95.  
  96.     bool isEmpty() {
  97.         return first == 0;
  98.     }
  99. };
  100. class Stack {
  101. public:
  102.     CharElement* first;
  103.     Stack() {
  104.         first = 0;
  105.     }
  106.     ~Stack() {
  107.         while (!isEmpty()) pop();
  108.     }
  109.     void push(char e) {
  110.         CharElement* e1 = new CharElement(e);
  111.         e1->next = first;
  112.         first = e1;
  113.     }
  114.     char peek() {
  115.         return first->value;
  116.     }
  117.     char pop() {
  118.         CharElement* temp = first;
  119.         first = temp->next;
  120.         char ret = temp->value;
  121.         delete temp;
  122.         return ret;
  123.     }
  124.     bool isEmpty() {
  125.         return first == 0;
  126.     }
  127. };
  128. class LongStack {
  129. public:
  130.     LongElement* first;
  131.     LongStack() {
  132.         first = 0;
  133.     }
  134.     ~LongStack() {
  135.         while (!isEmpty()) pop();
  136.     }
  137.     void push(long long e) {
  138.         LongElement* e1 = new LongElement(e);
  139.         e1->next = first;
  140.         first = e1;
  141.     }
  142.     long long peek() {
  143.         return first->value;
  144.     }
  145.     long long pop() {
  146.         LongElement* temp = first;
  147.         first = temp->next;
  148.         long long ret = temp->value;
  149.         delete temp;
  150.         return ret;
  151.     }
  152.     bool isEmpty() {
  153.         return first == 0;
  154.     }
  155. };
  156. class Queue {
  157. public:
  158.     StringElement* first;
  159.     StringElement* last;
  160.     Queue() {
  161.         first = 0;
  162.         last = 0;
  163.     }
  164.     ~Queue() {
  165.         while (!isEmpty()) pop();
  166.     }
  167.     void push(string e) {
  168.         StringElement* e1 = new StringElement(e);
  169.         if (first == 0) {
  170.             first = e1;
  171.             last = e1;
  172.         } else {
  173.             last->next = e1;
  174.             last = e1;
  175.         }
  176.     }
  177.     string peek() {
  178.         return first->value;
  179.     }
  180.     string pop() {
  181.         StringElement* temp = first;
  182.         first = temp->next;
  183.         string ret = temp->value;
  184.         delete temp;
  185.         return ret;
  186.     }
  187.     bool isEmpty() {
  188.         return first == 0;
  189.     }
  190. };
  191. int min(int a, int b) {
  192.     return a > b ? b : a;
  193. }
  194.  
  195. Queue* split(string &text, char delimiter)
  196. {
  197.     size_t pos = text.find( delimiter );
  198.     size_t initialPos = 0;
  199.     Queue* queue = new Queue();
  200.     while( pos != string::npos ) {
  201.         queue->push( text.substr( initialPos, pos - initialPos ) );
  202.         initialPos = pos + 1;
  203.         pos = text.find( delimiter, initialPos );
  204.     }
  205.     queue->push( text.substr( initialPos, min( pos, text.size() ) - initialPos + 1 ) );
  206.     return queue;
  207. }
  208. bool isOperator(char c) {
  209.     return c == '+' || c == '~' || c == '*' || c == 'd' || c == 'm' || c == '^';
  210. }
  211. bool isOpening(char c) {
  212.     return c == '[' || c == '{' || c == '(';
  213. }
  214. bool isClosing(char c) {
  215.     return c == ']' || c == '}' || c == ')';
  216. }
  217. bool isSameType(char o, char c) {
  218.     return (o == '[' && c == ']') || (o == '(' && c == ')') || (o == '{' && c == '}');
  219. }
  220.  
  221. int priority(char c) {
  222.     if (c == '+' || c == '~') return 1;
  223.     if (c == '*' || c == 'd' || c == 'm') return 2;
  224.     if (c == '^') return 3;
  225.     return 0;
  226. }
  227. long long stringToLong(string s) {
  228.     long long i;
  229.     istringstream iss(s);
  230.     iss >> i;
  231.     return i;
  232. }
  233. string toString(int i) {
  234.     ostringstream oss;
  235.     oss << i;
  236.     return oss.str();
  237. }
  238.  
  239. void replaceAll(string& str, const string& from, const string& to) {
  240.     if(from.empty())
  241.         return;
  242.     size_t start_pos = 0;
  243.     while((start_pos = str.find(from, start_pos)) != string::npos) {
  244.         str.replace(start_pos, from.length(), to);
  245.         start_pos += to.length();
  246.     }
  247. }
  248.  
  249. string toPostfix(string s) {
  250.     ostringstream oss;
  251.     Queue* q = split(s, ' ');
  252.     Stack* stack = new Stack();
  253.     while (!q->isEmpty()) {
  254.         string e = q->pop();
  255.         if (e.length() == 0) continue;
  256.         if (isOpening(e.at(0)) || isClosing(e.at(0))) continue;
  257.         else if (priority(e.at(0)) == 0) {
  258.             //replaceAll(e, " ", "");
  259.             oss << e << " ";
  260.         } else {
  261.             while (!stack->isEmpty() && priority(e.at(0)) <= priority(stack->peek())) {
  262.                 char s1 = stack->pop();
  263.                 oss << s1 << " ";
  264.             }
  265.             stack->push(e.at(0));
  266.         }
  267.     }
  268.     while (!stack->isEmpty()) {
  269.         oss << stack->pop() << " ";
  270.     }
  271.     delete q;
  272.     delete stack;
  273.     return oss.str();
  274. }
  275.  
  276. bool checkParen(string s) {
  277.     //sprawdzanie nawiasow
  278.     Stack* parens = new Stack();
  279.     for (int i = 0;i < s.length();i++) {
  280.         char c = s.at(i);
  281.         if (isOpening(c)) parens->push(c);
  282.         if (isClosing(c)) {
  283.             if (parens->isEmpty() || !isSameType(parens->peek(), c)) {
  284.                 cout << "bledne nawiasy";
  285.                 return true;
  286.             }
  287.             parens->pop();
  288.         }
  289.     }
  290.     if (!parens->isEmpty()) {
  291.         cout << "bledne nawiasy";
  292.         return true;
  293.     }
  294.     delete parens;
  295.     return false;
  296. }
  297.  
  298. bool checkSyntax(string s) {
  299.     //sprawdzanie składni
  300.     int SAME_NUMBER = 1;
  301.     int DIFF_NUMBER = 2;
  302.     int OPERATOR = 3;
  303.     int OPEN_PAREN = 4;
  304.     int CLOSE_PAREN = 5;
  305.  
  306.     int last = 0;
  307.     for (int i = 0;i < s.length();i++) {
  308.         char c = s.at(i);
  309.         if (c == ' ' && last == SAME_NUMBER) {
  310.             last = DIFF_NUMBER;
  311.             continue;
  312.         }
  313.         if (c == ' ') continue;
  314.         if (isOperator(c)) {
  315.             if (last == OPEN_PAREN || last == OPERATOR) {
  316.                 cout << "bledna skladnia";
  317.                 return true;
  318.             }
  319.             last = OPERATOR;
  320.             continue;
  321.         }
  322.         if (isOpening(c)) {
  323.             if (last == DIFF_NUMBER || last == CLOSE_PAREN) {
  324.                 cout << "bledna skladnia";
  325.                 return true;
  326.             }
  327.             last = OPEN_PAREN;
  328.             continue;
  329.         }
  330.         if (isClosing(c)) {
  331.             if (last == OPERATOR || last == OPEN_PAREN) {
  332.                 cout << "bledna skladnia";
  333.                 return true;
  334.             }
  335.             last = CLOSE_PAREN;
  336.             continue;
  337.         }
  338.         if (last == DIFF_NUMBER || last == CLOSE_PAREN) {
  339.             cout << "bledna skladnia";
  340.             return true;
  341.         }
  342.         last = SAME_NUMBER;
  343.         continue;
  344.     }
  345.     return false;
  346. }
  347.  
  348. void calculate(string s) {
  349.     LongStack* stack = new LongStack();
  350.     Queue* q = split(s, ' ');
  351.     while (!q->isEmpty()) {
  352.         string str = q->pop();
  353.         if (str.length() == 0) continue;
  354.         else if (isOperator(str.at(0))) {
  355.             long long l2 = stack->pop();
  356.             long long l1 = stack->pop();
  357.             char c = str.at(0);
  358.             if (c == '+')
  359.                 stack->push(l1 + l2);
  360.             else if (c == '~')
  361.                 stack->push(l1 - l2);
  362.             else if (c == '*')
  363.                 stack->push(l1 * l2);
  364.             else if (c == 'd') {
  365.                 if (l2 <= 0 || l1 < 0) {
  366.                     cout << "bledne dzialanie";
  367.                     return;
  368.                 }
  369.                 stack->push(l1 / l2);
  370.             }
  371.             else if (c == 'm') {
  372.                 if (l2 <= 0 || l1 < 0) {
  373.                     cout << "bledne dzialanie";
  374.                     return;
  375.                 }
  376.                 stack->push(l1 % l2);
  377.             }
  378.             else if (c == '^') {
  379.                 if ((l1 == 0 && l2 == 0) || l2 < 0) {
  380.                     cout << "bledne dzialanie";
  381.                     return;
  382.                 }
  383.                 long long res = 1;
  384.                 for (int i = 0;i < l2;i++) {
  385.                     res = res * l1;
  386.                 }
  387.                 stack->push(res);
  388.             }
  389.         }
  390.         else {
  391.             stack->push(stringToLong(str));
  392.         }
  393.     }
  394.     if (stack->isEmpty()) {
  395.         delete stack;
  396.         delete q;
  397.         cout << "bledne dzialanie";
  398.         return;
  399.     }
  400.     else {
  401.         cout << stack->pop();
  402.         delete stack;
  403.         delete q;
  404.     }
  405. }
  406.  
  407. int main()
  408. {
  409.     int number = 0;
  410.     cin >> number;
  411.     cin.get();
  412.     string s = "";
  413.     getline(cin, s);
  414.     Map* vars = new Map();
  415.     int varNum = 0;
  416.     if (checkParen(s)) return 0;
  417.     if (checkSyntax(s)) return 0;
  418.     while (true) {
  419.         int start = 0;
  420.         int end = 0;
  421.         char paren = ' ';
  422.         for (int i = 0; i < s.length();i++) {
  423.             if (isOpening(s.at(i))) {
  424.                 start = i;
  425.                 paren = s.at(i);
  426.             } else if (isClosing(s.at(i)) && isSameType(paren, s.at(i))) {
  427.                 end = i;
  428.                 break;
  429.             }
  430.         }
  431.         if (end != 0) {
  432.             string infix = s.substr(start, end - start + 1);
  433.             varNum++;
  434.             string postfix = toPostfix(infix);
  435.             vars->put(varNum, postfix);
  436.             string id = "A" + toString(varNum);
  437.             replaceAll(s, infix, id);
  438.         } else break;
  439.     }
  440.     s = toPostfix(s);
  441.     for (int i = varNum;i > 0;i--) {
  442.         replaceAll(s, "A" + toString(i), vars->get(i)->value);
  443.     }
  444.     while (s.find("  ", 0) != string::npos) {
  445.         replaceAll(s, "  ", " ");
  446.     }
  447.     calculate(s);
  448.     return 0;
  449. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement