Cod sursa(job #2560471)

Utilizator gabrielbGabriel baraboi gabrielb Data 28 februarie 2020 01:32:07
Problema Evaluarea unei expresii Scor 40
Compilator py Status done
Runda Arhiva educationala Marime 3.89 kb
import re


class Stack(object):
    def __init__(self):
        self.items = []

    def __str__(self):
        return "{}".format(self.items)

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)


def getPriority(operator):
    if (operator == '+') or (operator == '-'):
        return 1
    if (operator == '*') or (operator == '/'):
        return 2
    return 0


def calculate(operand1, operand2, operator):
    if operator == '+':
        return operand1 + operand2
    if operator == '-':
        return operand1 - operand2
    if operator == '*':
        return operand1 * operand2
    if operator == '/':
        return operand1 / operand2


def splitExpression(expr):
    arr = re.split("([+-/*()])", expr.replace(" ", ""))
    for i in arr:
        if i == '':
            arr.remove(i)
    return arr


def main(expr):
    exprSplit = splitExpression(expr)
    inc = 0
    while 0 < len(exprSplit):
        currentElement = exprSplit[0]
        exprSplit.pop(0)
        if currentElement.isdigit():
            operands.push(int(currentElement))

        if currentElement == '(':
            inc += 10
        elif currentElement == ')':
            inc -= 10

        if currentElement in '+-*/':
            operatorCurrentElement = currentElement
            priorityCurrentElement = getPriority(operatorCurrentElement) + inc

            if operators.isEmpty():
                priorities.push(getPriority(currentElement) + inc)
                operators.push(currentElement)

            else:
                operatorPred = operators.peek()
                priorityPred = priorities.peek()

                if priorityPred < priorityCurrentElement:
                    operators.push(operatorCurrentElement)
                    priorities.push(priorityCurrentElement)

                else:
                    smaller = True

                    while smaller:
                        operators.pop()
                        priorities.pop()
                        operand2 = operands.pop()
                        operand1 = operands.pop()
                        operands.push(calculate(operand1, operand2, operatorPred))
                        # print(operand1, operatorPred, operand2, '=', calculate(operand1, operand2, operatorPred))

                        if not operators.isEmpty():
                            operatorPred = operators.peek()
                            priorityPred = priorities.peek()

                            if priorityPred < priorityCurrentElement:
                                smaller = False
                                operators.push(operatorCurrentElement)
                                priorities.push(priorityCurrentElement)

                        else:
                            smaller = False
                            operators.push(operatorCurrentElement)
                            priorities.push(priorityCurrentElement)

    while 0 < operators.size():

        operator = operators.peek()
        operators.pop()
        operand2 = operands.pop()
        operand1 = operands.pop()
        operands.push(calculate(operand1, operand2, operator))

    return operands.peek()


expression = ''
operands = Stack()                          # Operands Stack
operators = Stack()                         # Operators Stack
priorities = Stack()                        # Priorities Stack

if __name__ == '__main__':
    with open('evaluare.in', 'r') as f:
        s = f.readline()
    result = main(s)
    result = round(result)

    with open('evaluare.out', 'w') as f:
        f.write(str(result))
    # print('Result: ', main(expression))