Skip to content

Instantly share code, notes, and snippets.

@rkdgusrn1212
Created August 17, 2022 07:43
Show Gist options
  • Save rkdgusrn1212/e355efbfc0d3baaeaf35c9c3bfe005ed to your computer and use it in GitHub Desktop.
Save rkdgusrn1212/e355efbfc0d3baaeaf35c9c3bfe005ed to your computer and use it in GitHub Desktop.
자바 수식 계산기(연산자 우선순위 고려)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
/**
* 피연산자 여러개 연산 가능합니다.
*
* ***예제1***
* 수식을 한 줄에 입력해주세요.
* 23*12-37/23%12+23
* 297.39130434782606
* 다시하려면 Y/y를 입력하세요.
* ***********
* @author 강현구
*
*/
public class ExpCalculator {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
while(true) {
Stack<Character> operatorStack = new Stack<>();
Stack<Double> operandStack = new Stack<>();
System.out.println("수식을 한 줄에 입력해주세요.");
String inStr = br.readLine();
String[] operands = inStr.split("[+-/*%]");
int[] operandNums = new int[operands.length];
boolean againFlag = false;
for(int i=0 ; i< operands.length; i++) {
if(operands[i].length()<1) {
System.out.println("피연산자 수가 부족합니다.");
againFlag = true;
break;
}
try {
operandNums[i] = Integer.parseInt(operands[i].trim());
}catch(NumberFormatException ex) {
System.out.println("피연산자가 숫자여야 합니다.");
againFlag = true;
break;
}
}
if(againFlag) continue;
if(operands.length < 2) {
System.out.println("피연산자가 2개 이상이어야 합니다.");
continue;
}
char[] operatorChars = new char[operands.length-1];
int operatorIdx=0;
for(char c : inStr.toCharArray()) {
if(c=='*'||c=='/'||c=='+'||c=='-'||c=='%') {
if(operatorIdx>=operatorChars.length) {
System.out.println("피연산자 수가 부족합니다.");
againFlag = true;
break;
}
operatorChars[operatorIdx++] = c;
}
}
if(againFlag) continue;
//여기서부턴 연산 시작
operandStack.push((double) operandNums[0]);
operatorIdx = 0;
while(operatorIdx<operatorChars.length) {
int nextOperand = operandNums[operatorIdx+1];
char nextOperator = operatorChars[operatorIdx];
if(!operatorStack.empty() && getOperatorPriority(operatorStack.peek())>=getOperatorPriority(nextOperator)) {
//스텍의 등급이 그 다음 연산자보다 같거다 크면
//그 부분을 연산해서 결과를 다시 스텍에 저장한다.
double opr2 = operandStack.pop();
double opr1 = operandStack.pop();
operandStack.push(calculate(opr1, opr2, operatorStack.pop()));
}else {
//스택에 넣기
operandStack.push((double)nextOperand);
operatorStack.push(nextOperator);
operatorIdx++;
}
}
while(!operatorStack.empty()) {
double opr2 = operandStack.pop();
double opr1 = operandStack.pop();
operandStack.push(calculate(opr1, opr2, operatorStack.pop()));
}
System.out.println("="+operandStack.peek());
System.out.println("다시하려면 Y/y를 입력하세요.");
String respond = br.readLine().trim();
if(respond.length()!=1 || (respond.charAt(0)!='Y' && respond.charAt(0)!='y')) break;
}
br.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("IOException이 발생하였습니다.");
}
}
//연산자가 아닐순 없지만 아니면 -1.
private static int getOperatorPriority(char c) {
switch(c) {
case '*':
case '/':
case '%':
return 2;
case '+':
case '-':
return 1;
}
return -1;
}
private static double calculate(double opr1, double opr2, char c) {
switch(c) {
case '*':
return opr1*opr2;
case '/':
return opr1/opr2;
case '%':
return opr1%opr2;
case '+':
return opr1+opr2;
case '-':
return opr1-opr2;
}
return -1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment