코딩 문제

[코딩 문제] Calculator

Joo.v7 2024. 9. 8. 22:04

문제

터미널에서 동작하는 계산기 프로그램 작성

터미널에서 실행되는 계산기를 작성합니다. 계산기는 4칙 연산(더하기, 빼기, 나누기, 곱하기)만을 지원하며, 괄호는 포함하지 않습니다. 연산자의 우선 순위는 지켜져야 합니다.

 

프로그램 요구 사항

  • 프로그램이 실행되면 아래와 같이 > 기호를 프롬프트로 보여줍니다.
  • 수식을 입력하면 계산 후 결과를 보여줍니다.
  • 계산은 연속해서 동작해야 합니다.
  • exit() 를 입력하면 프로그램이 종료됩니다.
  • 수식이 잘못 입력 되었을 경우, InvalidExpressionException을 일으킵니다.
  • 프로그램의 수식은 Abstract Syntax Tree를 이용해서 계산되도록 작성되어야 하며, 아래 메소드는 AST를 반환하도록 작성되어야 합니다.
  • generateAST 메소드를 호출하면 아래와 같은 출력을 보여야 합니다.
  • 프로그램은 계산 결과를 반환하는 evaluation() 함수를 가지고 있어야 합니다.

 

코드

import java.util.Stack;
import java.util.Scanner;

class Node {
    String key;
    Node left;
    Node right;

    public Node() {}

    public Node(String key) {
        this.key = key;
        this.left = this.right = null;
    }

    public Node(String key, Node left, Node right) {
        this.key = key;
        this.left = left;
        this.right = right;
    }

    public String toString() {
        if (left == null && right == null) {
            return "(" + key + ")";
        }
        return "(" + left + "," + key + "," + right + ")";
    }
}

public class Calculator<E> {
    private int priority(char op) {
        if (op == '*' || op == '/') { // 곱셈, 나눗셈 2
            return 2;
        } 
        else if (op == '+' || op == '-') { // 덧셈 뺄셈 1
            return 1;
        }
        return 0; // 숫자 0
    }

    // *중요* Checked Exception은 메서드 시그니처 뒤에 throws ~Exception 명시 해줘야함.
    public Node generateAST(String input) throws InvalidExpressionException {
        Stack<Node> operand = new Stack<>();
        Stack<Character> operator = new Stack<>();

        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);

            if ((c == '+') || (c == '-') || (c == '*') || (c == '/')) {
                while ((!operator.isEmpty()) && (priority(operator.peek()) >= priority(c))){
                    Node right = operand.pop();
                    Node left = operand.pop();
                    char op = operator.pop();
                    operand.push(new Node(String.valueOf(op), left, right));
                }
                operator.push(c);
            }
            else if (Character.isDigit(c)){ 
                StringBuilder s = new StringBuilder(); // StringBuilder: append()로 문자열 연결해줌
                while (i < input.length() && Character.isDigit(input.charAt(i))) {
                    s.append(input.charAt(i++));
                }
                i--;
                operand.push(new Node(s.toString()));
            }
            else if (c == ' ') {
                continue;
            }
            else {
                throw new InvalidExpressionException("wrong input");
            }
        }
        while (!operator.isEmpty()) {
            Node right = operand.pop();
            Node left = operand.pop();
            char op = operator.pop();
            operand.push(new Node(String.valueOf(op), left, right));
        }
        return operand.pop();
    }

    public int evaluation(Node node) throws InvalidExpressionException{
        if (node.left == null && node.right == null) {
            return Integer.parseInt(node.key);
        }

        int left = evaluation(node.left);
        int right = evaluation(node.right);

        if (node.key.charAt(0) == '+') {
            return left + right;
        }
        else if(node.key.charAt(0) == '-') {
            return left - right;
        }
        else if (node.key.charAt(0) == '*') {
            return left * right;
        }
        else if (node.key.charAt(0) == '/') {
            return left / right;
        }
        else {
            throw new InvalidExpressionException("wrong input");
        }
    }
}

// Checked Exception 오류를 사용자가 만든거임.
class InvalidExpressionException extends Exception { 
    public InvalidExpressionException(String message) {
        super(message);
    }
}

class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Calculator calculator = new Calculator();

        while(true) {
            try {
                System.out.print("> ");
                String input = scanner.nextLine();

                if (input.equals("exit()")) {
                    break;
                }

                
                Node ast = calculator.generateAST(input);
                System.out.println("AST: " + ast);

                int result = calculator.evaluation(ast);
                System.out.println(result);
            }
            catch (InvalidExpressionException e) {
                System.out.println("Your input is wrong");
            }
            catch (Exception e) {
                System.out.println("Your input is wrong");
            }
        }
        scanner.close();
    }
}

 

실행 결과

> 1 + 2 + 3 + 4 + 5
AST: (((((1),+,(2)),+,(3)),+,(4)),+,(5))
15
> 1 * 2 * 3 * 4 * 5
AST: (((((1),*,(2)),*,(3)),*,(4)),*,(5))
120
> exit()
// 종료

 

 

 

2024.09.02 - [Java] - [Java] 14. Collections Framework

 

[Java] 14. Collections Framework

Chapter 1: Collection FrameworkCollection 개요Java Collections FrameworkCollection 클래스의 저장 구조Java Collections Framework 구성Collection 인터페이스Collection 인터페이스의 주요 메소드 Chapter 2: Iterator, Comparable, Compa

lightningtech.tistory.com

 


 

 

출처: https://github.com/gikpreet/class-programming_with_java/tree/master

 

GitHub - gikpreet/class-programming_with_java

Contribute to gikpreet/class-programming_with_java development by creating an account on GitHub.

github.com

 

'코딩 문제' 카테고리의 다른 글

[코딩 문제] 문자열 반전  (0) 2024.08.30
[코딩 문제] Palindrom  (0) 2024.08.23
[코딩 문제] 연도 일자를 월/일로 계산하기  (0) 2024.08.23
[코딩 문제] 미로 탐색  (0) 2024.08.23
[코딩 문제] TicTacToe 게임  (0) 2024.08.23