stack을 이용한 후위표기법 계산

박진은·2022년 5월 5일
0

자료구조

목록 보기
3/37

후위표기법

class stack:
    def __init__(self):
        self.top = []

    def isEmpty(self):
        return len(self.top) == 0

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

    def pop(self):
        if len(self.top) != 0:
            return self.top.pop(-1)  # -1 대신에 length of top 에 -1도 가능합니다.

    def peek(self):
        if len(self.top) != 0:
            return self.top[-1]

    def display(self):
        print(self.top)

    def __sizeof__(self):
        return len(self.pop)

    def __str__(self):
        return str(self.top)

스택 클래스

def evalPostfix(expr):
    s = stack()
    for token in expr:
        if token in '+-/*':
            val2 = s.pop()
            val1 = s.pop()
            if token == '+':
                s.push(val1 + val2)
            elif token == '*':
                s.push(val1 * val2)
            elif token == '-':
                s.push(val1 - val2)
            elif token == '/':
                s.push(val1 / val2)
            elif token == '%':
                s.push(val1 % val2)
        else:
            s.push(float(token))

    return s.pop()

후위 표기법 계산하는거 근데 이거 여기서 val2 랑 val1 순서 바꾸면 뺄샘 결과가 바뀐다 개같은거

def precedence(op):
    if op in '()':
        return 0
    elif op in '+-':
        return 1
    elif op in '*/':
        return 2
    else:
        return -1

연산자 우선순위 반환하는 함수

def Infix2Postfix(expr):  # 입력값 리스트
    s = stack()
    output = []

    for term in expr:
        if term == '(':  # 왼쪽괄호라면바로스택에 추가
            s.push(term)
        elif term == ')':  # 오른쪽 괄호를 만나면 그동안 스택에 들어있던 연산자 모두 출력
            while not s.isEmpty():
                op = s.pop()
                if op == '(':  # 왼쪽괄호가 나오면 출력중지
                    break
                else:
                    output.append(op)  # 왼쪽괄호가 아니며 전부 리스트 뒤로 추가
        elif term in '+-/*':  # 연산자이면
            while not s.isEmpty():
                op = s.peek()  # 스택에서 객체를 참조하고 삭제하지 않는 메소드
                if (precedence(term) <= precedence(op)):  # 우선순위가 높거나 같은 연산자들을 모두 출력
                    output.append(op)  # 우선순위가 같아도 출력하는 이유는 같은 우선순위에서도 출력하지 않으면 계산순서가 뒤바뀐다.
                    s.pop()  # 스택에서 객체를 반환하고 스택에서 삭제하는 메소드
                else:
                    break
            s.push(term)  # 연산자가 아니면 객체에 색입
        else:
            output.append(term)

    while not s.isEmpty():
        output.append(s.pop())

    return output

expr = input("중위표기 수식을 공백을 기준으로 입력하세요")
expr = expr.split()#공백을 기준으로 문자열을 잘라서 리스트 생성후 다시 반환
postfix = Infix2Postfix(expr)
print(evalPostfix(postfix))
#

중위 표기법을 후위 표기법으로 전환하는 방법

함수위 대표적인 알고리즘을 정리하면

  • 먼저 출력할 리스트와 연산자들을 쌓아둘 스택을 만들어
  1. 괄호인지 아닌지 검사해서 괄호이면 바로 처 넣어
  2. 왼쪽 괄호를 위에서 넣어놨을 거야 그러니까 바로 오른쪽 괄호를 만나면 왼족 괄호를 만날때까지 스택에 넣어둔 연산자들을 모두 빼서 출력하는 리스트에 처 넣어
  3. 그담에 고려할 사항이 연산자들을 만나는 거야 연산자들을 만나는데 이때 안에 들어있는 연산자를 pop연산자 말고 peek연산자를 사용해서 빼지말고 참조만하고 이번에 만난연산자를 procedence 메서드를 사용해서 우선순위를 비교하는 거야 연산자를 비교해서 이번 반복문에서 만난연산자랑 안에 들어있는 연산자랑 비교를 하는데 이번에 반복문에 들어가는 연산자의 우선수가 작거나 같으면 스택안에 들어있는 연산자들을 다 빼 그담에 전부다 출력하려는 리스트에 삽입하는거여 오키?
  4. 나머지는 피 연산자들을 취급하는데 연산자가 아니면 전부다 출력하려는 리스트에 처 넣어 주세용
profile
코딩

0개의 댓글