티스토리 뷰

반응형

사칙연산 프로그램이 필요해서 만들었다.

추가로 sqrt, abs, power 연산도 추가했다. (아직 에러는 없는데 혹시 나올수도? ㅎㅎ)

 

import java.util.*;

public class StringCalculator {
    
    public double evaluate(String expression) {
        Stack<Double> numbers = new Stack<>();
        Stack<Character> operations = new Stack<>();
        
        expression = expression.toLowerCase();
        
        for (int i = 0; i < expression.length(); i++) {
            char ch = expression.charAt(i);
            if (ch == '(') {
                operations.push(ch);
            }
            else if (ch == ')') {
                while (operations.peek() != '(') {
                    char operator = operations.pop();
                    double operand2 = numbers.pop();
                    double operand1 = numbers.pop();
                    double result = performOperation(operand1, operand2, operator);
                    numbers.push(result);
                }
                if(operations.size() != 0 && operations.peek() == '(') operations.pop();
            } 
            else if (ch == '-' 
                  && (i == 0 || (!Character.isDigit(expression.charAt(i-1)) 
                  && expression.charAt(i-1) != ')'))) {
                numbers.push(0.);
                operations.push('-');
                continue;
            } 
            else if ( ch == 's' 
                  && expression.charAt(i+1) == 'q' 
                  && expression.charAt(i+2) == 'r'  
                  && expression.charAt(i+3) == 't' ) {
                numbers.push(0.);
                operations.push('s');
                i+=3;
                continue;
            } 
            else if ( ch == 'a' 
                  && expression.charAt(i+1) == 'b' 
                  && expression.charAt(i+2) == 's' ) {
                numbers.push(0.);
                operations.push('a');
                i+=2;
                continue;
            } 
            else if (Character.isDigit(ch) || ch == '.') {
                double number = 0;
                int decimalPlace = 0;
                boolean isDecimal = false;
                while (i < expression.length() 
                      && (Character.isDigit(expression.charAt(i)) 
                      || expression.charAt(i) == '.')) {
                    char currentChar = expression.charAt(i);
                    if (currentChar == '.') {
                        isDecimal = true;
                        i++;
                        continue;
                    }
                    if (isDecimal) {
                        decimalPlace++;
                    }
                    number = number * 10 + (currentChar - '0');
                    i++;
                }
                if (isDecimal) {
                    number = number / Math.pow(10, decimalPlace);
                }
                i--;
                numbers.push(number);
            } 
            else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^') {
                while (!operations.isEmpty() && hasPrecedence(ch, operations.peek())) {
                    double operand2 = numbers.pop();
                    double operand1 = numbers.pop();
                    char operator = operations.pop();
                    double result = performOperation(operand1, operand2, operator);
                    numbers.push(result);
                }
                operations.push(ch);
            }
        }
        while (!operations.isEmpty()) {
            double operand2 = numbers.pop();
            double operand1 = numbers.pop();
            char operator = operations.pop();
            double result = performOperation(operand1, operand2, operator);
            numbers.push(result);
        }
        return numbers.pop();
    }
    
    private static double performOperation(double operand1, double operand2, char operator) {
        switch (operator) {
            case '+':
                return operand1 + operand2;
            case '-':
                return operand1 - operand2;
            case '*':
                return operand1 * operand2;
            case '/':
                return operand1 / operand2;
            case 's':
                return Math.sqrt(operand2);
            case 'a':
                return Math.abs(operand2);
            case '^':
                return Math.pow(operand1, operand2);
        }
        return 0;
    }
    
    private static boolean hasPrecedence(char operator1, char operator2) {
        if (operator2 == '(' || operator2 == ')') {
            return false;
        }
        if ((operator1 == '*' || operator1 == '/') 
              && (operator2 == '+' || operator2 == '-')) {
            return false;
        }
        return true;
    }

}

사용

@Test
void test() {
	StringCalculator calculator = new StringCalculator();
	String input = "(4+5-2) * sqrt(8-4) + (5*6)";
    double result = calculator.evaluate(input);
    System.out.println("입력:" + input);
	System.out.println("출력:" + result);
}

결과:

반응형
반응형
최근에 달린 댓글