Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <sstream>
- using namespace std;
- class CharElement {
- public:
- CharElement* next;
- char value;
- CharElement(char value) {
- this->value = value;
- next = 0;
- }
- };
- class LongElement {
- public:
- LongElement* next;
- long long value;
- LongElement(long long value) {
- this->value = value;
- next = 0;
- }
- };
- class StringElement {
- public:
- StringElement* next;
- string value;
- StringElement(string value) {
- this->value = value;
- next = 0;
- }
- };
- class Entry {
- public:
- Entry* next;
- int key;
- string value;
- };
- class Map {
- public:
- Entry* first;
- Entry* last;
- Map() {
- first = 0;
- last = 0;
- }
- ~Map() {
- while (!isEmpty()) {
- remove(first->key);
- }
- }
- void put(int key, string value) {
- Entry* e = get(key);
- if (e == 0) {
- e = new Entry();
- e->key = key;
- e->value = value;
- if (first == 0) {
- first = e;
- } else {
- last->next = e;
- }
- last = e;
- } else {
- e->value = value;
- }
- }
- Entry* get(int key) {
- Entry* e = first;
- while (e != 0) {
- if (e->key == key) return e;
- e = e->next;
- }
- return 0;
- }
- void remove(int key) {
- Entry* e = first;
- if (e != 0 && e->key == key) {
- first = e->next;
- delete e;
- }
- else {
- while (e != 0) {
- if (e->next != 0 && e->next->key == key) {
- Entry* del = e->next;
- e->next = del->next;
- delete del;
- break;
- }
- }
- }
- }
- bool isEmpty() {
- return first == 0;
- }
- };
- class Stack {
- public:
- CharElement* first;
- Stack() {
- first = 0;
- }
- ~Stack() {
- while (!isEmpty()) pop();
- }
- void push(char e) {
- CharElement* e1 = new CharElement(e);
- e1->next = first;
- first = e1;
- }
- char peek() {
- return first->value;
- }
- char pop() {
- CharElement* temp = first;
- first = temp->next;
- char ret = temp->value;
- delete temp;
- return ret;
- }
- bool isEmpty() {
- return first == 0;
- }
- };
- class LongStack {
- public:
- LongElement* first;
- LongStack() {
- first = 0;
- }
- ~LongStack() {
- while (!isEmpty()) pop();
- }
- void push(long long e) {
- LongElement* e1 = new LongElement(e);
- e1->next = first;
- first = e1;
- }
- long long peek() {
- return first->value;
- }
- long long pop() {
- LongElement* temp = first;
- first = temp->next;
- long long ret = temp->value;
- delete temp;
- return ret;
- }
- bool isEmpty() {
- return first == 0;
- }
- };
- class Queue {
- public:
- StringElement* first;
- StringElement* last;
- Queue() {
- first = 0;
- last = 0;
- }
- ~Queue() {
- while (!isEmpty()) pop();
- }
- void push(string e) {
- StringElement* e1 = new StringElement(e);
- if (first == 0) {
- first = e1;
- last = e1;
- } else {
- last->next = e1;
- last = e1;
- }
- }
- string peek() {
- return first->value;
- }
- string pop() {
- StringElement* temp = first;
- first = temp->next;
- string ret = temp->value;
- delete temp;
- return ret;
- }
- bool isEmpty() {
- return first == 0;
- }
- };
- int min(int a, int b) {
- return a > b ? b : a;
- }
- Queue* split(string &text, char delimiter)
- {
- size_t pos = text.find( delimiter );
- size_t initialPos = 0;
- Queue* queue = new Queue();
- while( pos != string::npos ) {
- queue->push( text.substr( initialPos, pos - initialPos ) );
- initialPos = pos + 1;
- pos = text.find( delimiter, initialPos );
- }
- queue->push( text.substr( initialPos, min( pos, text.size() ) - initialPos + 1 ) );
- return queue;
- }
- bool isOperator(char c) {
- return c == '+' || c == '~' || c == '*' || c == 'd' || c == 'm' || c == '^';
- }
- bool isOpening(char c) {
- return c == '[' || c == '{' || c == '(';
- }
- bool isClosing(char c) {
- return c == ']' || c == '}' || c == ')';
- }
- bool isSameType(char o, char c) {
- return (o == '[' && c == ']') || (o == '(' && c == ')') || (o == '{' && c == '}');
- }
- int priority(char c) {
- if (c == '+' || c == '~') return 1;
- if (c == '*' || c == 'd' || c == 'm') return 2;
- if (c == '^') return 3;
- return 0;
- }
- long long stringToLong(string s) {
- long long i;
- istringstream iss(s);
- iss >> i;
- return i;
- }
- string toString(int i) {
- ostringstream oss;
- oss << i;
- return oss.str();
- }
- void replaceAll(string& str, const string& from, const string& to) {
- if(from.empty())
- return;
- size_t start_pos = 0;
- while((start_pos = str.find(from, start_pos)) != string::npos) {
- str.replace(start_pos, from.length(), to);
- start_pos += to.length();
- }
- }
- string toPostfix(string s) {
- ostringstream oss;
- Queue* q = split(s, ' ');
- Stack* stack = new Stack();
- while (!q->isEmpty()) {
- string e = q->pop();
- if (e.length() == 0) continue;
- if (isOpening(e.at(0)) || isClosing(e.at(0))) continue;
- else if (priority(e.at(0)) == 0) {
- //replaceAll(e, " ", "");
- oss << e << " ";
- } else {
- while (!stack->isEmpty() && priority(e.at(0)) <= priority(stack->peek())) {
- char s1 = stack->pop();
- oss << s1 << " ";
- }
- stack->push(e.at(0));
- }
- }
- while (!stack->isEmpty()) {
- oss << stack->pop() << " ";
- }
- delete q;
- delete stack;
- return oss.str();
- }
- bool checkParen(string s) {
- //sprawdzanie nawiasow
- Stack* parens = new Stack();
- for (int i = 0;i < s.length();i++) {
- char c = s.at(i);
- if (isOpening(c)) parens->push(c);
- if (isClosing(c)) {
- if (parens->isEmpty() || !isSameType(parens->peek(), c)) {
- cout << "bledne nawiasy";
- return true;
- }
- parens->pop();
- }
- }
- if (!parens->isEmpty()) {
- cout << "bledne nawiasy";
- return true;
- }
- delete parens;
- return false;
- }
- bool checkSyntax(string s) {
- //sprawdzanie składni
- int SAME_NUMBER = 1;
- int DIFF_NUMBER = 2;
- int OPERATOR = 3;
- int OPEN_PAREN = 4;
- int CLOSE_PAREN = 5;
- int last = 0;
- for (int i = 0;i < s.length();i++) {
- char c = s.at(i);
- if (c == ' ' && last == SAME_NUMBER) {
- last = DIFF_NUMBER;
- continue;
- }
- if (c == ' ') continue;
- if (isOperator(c)) {
- if (last == OPEN_PAREN || last == OPERATOR) {
- cout << "bledna skladnia";
- return true;
- }
- last = OPERATOR;
- continue;
- }
- if (isOpening(c)) {
- if (last == DIFF_NUMBER || last == CLOSE_PAREN) {
- cout << "bledna skladnia";
- return true;
- }
- last = OPEN_PAREN;
- continue;
- }
- if (isClosing(c)) {
- if (last == OPERATOR || last == OPEN_PAREN) {
- cout << "bledna skladnia";
- return true;
- }
- last = CLOSE_PAREN;
- continue;
- }
- if (last == DIFF_NUMBER || last == CLOSE_PAREN) {
- cout << "bledna skladnia";
- return true;
- }
- last = SAME_NUMBER;
- continue;
- }
- return false;
- }
- void calculate(string s) {
- LongStack* stack = new LongStack();
- Queue* q = split(s, ' ');
- while (!q->isEmpty()) {
- string str = q->pop();
- if (str.length() == 0) continue;
- else if (isOperator(str.at(0))) {
- long long l2 = stack->pop();
- long long l1 = stack->pop();
- char c = str.at(0);
- if (c == '+')
- stack->push(l1 + l2);
- else if (c == '~')
- stack->push(l1 - l2);
- else if (c == '*')
- stack->push(l1 * l2);
- else if (c == 'd') {
- if (l2 <= 0 || l1 < 0) {
- cout << "bledne dzialanie";
- return;
- }
- stack->push(l1 / l2);
- }
- else if (c == 'm') {
- if (l2 <= 0 || l1 < 0) {
- cout << "bledne dzialanie";
- return;
- }
- stack->push(l1 % l2);
- }
- else if (c == '^') {
- if ((l1 == 0 && l2 == 0) || l2 < 0) {
- cout << "bledne dzialanie";
- return;
- }
- long long res = 1;
- for (int i = 0;i < l2;i++) {
- res = res * l1;
- }
- stack->push(res);
- }
- }
- else {
- stack->push(stringToLong(str));
- }
- }
- if (stack->isEmpty()) {
- delete stack;
- delete q;
- cout << "bledne dzialanie";
- return;
- }
- else {
- cout << stack->pop();
- delete stack;
- delete q;
- }
- }
- int main()
- {
- int number = 0;
- cin >> number;
- cin.get();
- string s = "";
- getline(cin, s);
- Map* vars = new Map();
- int varNum = 0;
- if (checkParen(s)) return 0;
- if (checkSyntax(s)) return 0;
- while (true) {
- int start = 0;
- int end = 0;
- char paren = ' ';
- for (int i = 0; i < s.length();i++) {
- if (isOpening(s.at(i))) {
- start = i;
- paren = s.at(i);
- } else if (isClosing(s.at(i)) && isSameType(paren, s.at(i))) {
- end = i;
- break;
- }
- }
- if (end != 0) {
- string infix = s.substr(start, end - start + 1);
- varNum++;
- string postfix = toPostfix(infix);
- vars->put(varNum, postfix);
- string id = "A" + toString(varNum);
- replaceAll(s, infix, id);
- } else break;
- }
- s = toPostfix(s);
- for (int i = varNum;i > 0;i--) {
- replaceAll(s, "A" + toString(i), vars->get(i)->value);
- }
- while (s.find(" ", 0) != string::npos) {
- replaceAll(s, " ", " ");
- }
- calculate(s);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement