터미널에서 실행되는 계산기를 작성합니다. 계산기는 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 |