본문 바로가기
Algorithm Problem Solving/SW Expert Academy

[Python] SWEA 4874 Forth

by ʚ⇜❅🎕̈❄⇝ɞ 2021. 8. 3.
728x90
반응형

SWEA 파이썬 문제 해결 SW Expert Academy 4874 Forth 문제는 스택 연산을 기반으로 하고 있어서 후위 표기법을 사용하는 Forth라는 컴퓨터 언어의 코드 연산 결과를 출력하는 문제이다. 자료구조 스택을 활용한 계산기 프로그램에 관한 문제로 난이도는 D2이다.

 

SW Expert Academy 4874번 Forth 문제 정보

자료구조 분류

- Stack

난이도

- D2

 

Forth 문제 요약

  • Forth 언어는 후위 표기법을 사용한다.  ex) 3+4 → 3 4 + .
  • Forth에서의 동작은 아래와 같다.
  • 1. 숫자는 스택에 넣는다.
  • 2. 연산자를 만나면 스택의 숫자 두 개를 꺼내어 연산하고 결과를 다시 스택에 넣는다.
  • 3. '.'은 스택에서 숫자를 꺼내 출력한다.
  • Forth 코드의 연산 결과를 출력한다. 만약 형식의 오류로 연산이 불가할 경우 'error'를 출력한다.
  • 정수와 연산자가 256자 이내의 연산 코드가 주어지고 피연산자와 연산자는 여백으로 구분되어 있으며, 코드는 '.'로 끝난다.
  • 나눗셈의 경우 항상 나누어 떨어진다.

문제 풀이 과정

  1. 입력받은 연산 코드가. 을 만나기 전까지
  2. 숫자면 스택에 push 하고
  3. 연산자이고 스택에 숫자가 2개 이상 있다면 연산하고 그 결과를 스택에 push 한다.
    • fail 이유: 나눗셈의 경우 항상 나누어 떨어진다고 했으므로 연산자 /를 //로 바꾼다.
  4. 그 외에는 연산 코드의 형식상의 오류이므로 error를 리턴한다.
  5. 연산 코드가 끝나고 나서 스택에 숫자가 1개일 경우 연산 결과를 리턴한다.
  6. 스택에 숫자가 2개 이상 남는 경우에는 연산자가 모자라는 형식의 오류이므로 error를 리턴한다.
    • 채점 결과 fail 원인: 1 2 + 3 . 과 같은 에러 처리 미흡
  7. 테스트 케이스 번호, forth 연산 결과를 출력한다.
코드 및 설명
  • second - stack에서 숫자 2개를 꺼낼 때, 맨 위 값이 연산의 2번째 피연산자가 되어야 하고,
  • first - 맨 위에서 2번째 값이 연산의 첫 번째 피연산자가 되어야 합니다.
  • 18번 줄 - python eval() 함수를 사용하여 python 코드를 입력으로 받아 문자열을 실행한 결과 값을 스택에 push 합니다.
def forth(operation_code):
    stack = list()
    i = 0
    
    # 연산 코드가 끝날 때까지
    while operation_code[i] != '.':
    
        # 숫자면 스택에 push
        if operation_code[i].isdigit():
            stack.append(operation_code[i])
            
        # 연산자이고 스택에 숫자가 2개 이상이면
        elif operation_code[i] in ('+', '-', '*', '/') and len(stack) >= 2:           
            if operation_code[i] == '/':
                operation_code[i] = '//'                
            second = str(stack.pop())
            first = str(stack.pop())
            stack.append(eval(first + operation_code[i] + second))
            
        else:
            return 'error'
            
        i += 1
        
    if len(stack) == 1:
        return stack[0]
    else:
        return 'error'

for tc in range(int(input())):
    print("#{} {}".format(tc + 1, forth(list(input().split()))))

이번 문제는 난이도가 D2인 간단한 문제이지만, 채점 결과 fail을 2번이나 만났다.

첫 번째 fail 원인은 나눗셈은 항상 나누어 떨어져야 한다는 조건이 있었는데 빠뜨린 실수였다.

두 번째 fail 이유는 연산자가 모자라는 경우의 테스트 케이스 에러 처리 미흡으로 인한 실패였다.

에러가 날 수 있는 테스트 케이스를 찾는 능력을 더욱 길러야겠다.

 

SW Expert Academy SWEA 4874번 Forth 문제는 후위 표기법과 스택을 활용한 계산기 문제였다.

728x90
반응형

댓글