데굴데굴

[파이썬/실습] postfix (후위식) 계산기 만들기 본문

CS/자료구조

[파이썬/실습] postfix (후위식) 계산기 만들기

aemaaeng 2022. 6. 30. 01:43

* Stack 클래스를 정의하여 코드를 작성했다.

 

입력
1 2 3 + 4 / +

출력
2.2500

 

Stack 클래스 정의

  • push(value): 스택에 값을 넣음
  • pop(): 스택의 가장 위에 있는 값을 삭제 후 리턴, 스택이 비어있으면 "Stack is empty"를 출력
  • top(): 스택의 가장 위에 있는 값을 리턴, pop()과 마찬가지로 스택이 비어있으면 "Stack is empty"를 출력
  • __len__(): 스택의 길이 출력
  • isEmpty(): 스택이 비어있는지 아닌지 판단
class Stack:
	def __init__(self):
		self.items = []
	
	def push(self, val):
		self.items.append(val)
		
	def pop(self):
		try:
			return self.items.pop()
		except IndexError:
			print("Stack is Empty")
	
	def top(self):
		try:
			return self.items[-1]
		except IndexError:
			print("Stack is Empty")
	
	def __len__(self):
		return len(self.items)
	
	def isEmpty(self):
		return self.__len__() == 0

 

postfix 계산기 함수

1. 피연산자(숫자)를 저장하기 위한 스택 생성

def compute_postfix(postfix):
	oper = Stack()

 

2. 문자열을 리스트로 변환

	postfix_expr = postfix.split()

 

3. 리스트를 하나씩 살펴보며 연산 수행

	for token in postfix_expr:

 

3-1. 피연산자일 경우

		if token.isdigit():
			oper.push(int(token))

token이 숫자라면 스택에 push하여 연산자가 나올 때까지 대기하도록 한다.

이 숫자는 형태만 숫자일 뿐, 자료형은 문자열이기 때문에 연산을 수행하기 위해서는 int를 씌워준 후 push해야 한다.

 

3-2. 연산자일 경우

		elif token in '+-*/^':
			a = oper.pop()
			b = oper.pop()
			
			if token == '+':
				oper.push(b + a)
			elif token == '-':
				oper.push(b - a)
			elif token == '*':
				oper.push(b * a)
			elif token == '/':
				oper.push(b / a)
			elif token == '^':
				oper.push(b ** a)

이항연산자만 쓴다고 가정했기 때문에 스택에 들어있는 숫자 두 개를 pop하여 각각 변수 a, b에 저장한다.

연산자의 종류에 따라 경우를 나눠 연산을 수행한 후 stack에 다시 push한다.

 

4. 최종 값 리턴

	result = oper.pop()
	result_4 = '{:.4f}'.format(round(result, 4))
	
	return result_4

스택에 마지막으로 남은 값이 연산 결과이므로 이를 pop한다. 

내가 지금 수강 중인 강의에서는 소수점 4번째 자리까지 의무적으로 출력하는 것이 조건이라 코드를 따로 더 추가했다.

 

최종 코드

def compute_postfix(postfix):
	oper = Stack()
	
	postfix_expr = postfix.split()
	
	for token in postfix_expr:
		
		if token.isdigit():
			oper.push(int(token))
			
		elif token in '+-*/^':
			a = oper.pop()
			b = oper.pop()
			
			if token == '+':
				oper.push(b + a)
			elif token == '-':
				oper.push(b - a)
			elif token == '*':
				oper.push(b * a)
			elif token == '/':
				oper.push(b / a)
			elif token == '^':
				oper.push(b ** a)
	
	result = oper.pop()
	result_4 = '{:.4f}'.format(round(result, 4))
	
	return result_4


postfix = input()
postfix_result = compute_postfix(postfix)
print(postfix_result)

 

Comments