//1. 수식에서 첫번째 항목을 빼냅니다.
//2. 수식의 빼낸 항목이 피연산자라면 그대로 출력측으로 빼냅니다
//3. 수식의 빼낸 항목이 연산자라면 스택의 최상위 원소와 비교합니다.
//4. 빼낸 연산자의 우선순위가 스택의 최상위에 있는 원소보다 높으면 그대로 스택에 넣습니다.
//5. 그렇지 않다면 스택의 최상위 원소를 출력측으로 뺴내고 빼낸 연산자를 스택에 넣습니다.
//6. 단, 여는 괄호'('가 나오면 닫는괄호')'가 나올 때까지 스택에 남아있게 되며, 닫는괄호')'가 나타나면
그때까지 여는괄호'('보다 상위에 있는 모든 연산자를 출력측으로 빼냅니다.
정말 열심히 찾다가 어디선가 푸는 방식을 주석으로 코드에 넣은건데 출처를 잊었네요..
이 방법대로 구현하면 infix -> postfix 변환이 잘됩니다.
public class InfixToPostfix {
private Stack stack;
public String infix = "";
public String inputToPostfix = "";
public InfixToPostfix() {
this.stack = new Stack<>();
}
public Stack getStack() {
return stack;
}
public int calcPostfix(){
for(int i = 0; i < inputToPostfix.length(); i++){
char token = inputToPostfix.charAt(i);
System.out.println("clac token : " + token);
if(isNumber(token)) stack.push(Character.digit(token,10));
else{
int n1 = (Integer) stack.pop();
int n2 = (Integer) stack.pop();
int operateRes = operateToken(token,n2,n1);
System.out.println("operateRes : " + operateRes);
stack.push(operateRes);
}
System.out.println(stack);
}
return (Integer)stack.pop();
}
private int operateToken(char operater,int n1, int n2){
switch (operater){
case '*' :
return n1 * n2;
case '/' :
return n1 / n2;
case '+' :
return n1 + n2;
case '-' :
return n1 - n2;
}
return 0;
}
public String getOutput(){
pushInStackForPostfix();
return inputToPostfix;
}
private void pushInStackForPostfix(){
for(int i=0; i < infix.length(); i++){
char token = infix.charAt(i);
System.out.println("token : " + token);
if(isNumber(token)){
inputToPostfix += token;
}else{
if(token == '('){
stack.push(token);
}else{
sortOperater(token);
}
System.out.println("==out==\n" + inputToPostfix);
}
}
clearStack();
}
private void sortOperater(char input){
System.out.println("==stack==\n" + stack.toString() + "\n ====");
if(stack.empty()){ stack.push(input); return;}
if(input == ')'){
while(!stack.isEmpty()){
char inClose = (Character) stack.pop();
if(inClose == '(') break;
inputToPostfix += inClose;
}
}else {
int inputGarde = getOperaterGrade(input);
while (!stack.isEmpty()) {
char prev = (Character)stack.pop();
if(prev == '('){
stack.push(prev);
break;
}
int prevGarde = getOperaterGrade(prev);
if (prevGarde >= inputGarde) {
inputToPostfix += prev;
} else {
stack.push(prev);
break;
}
}
stack.push(input);
}
}
public boolean isNumber(char token){
if('0' <= token && token <= '9')
return true;
else
return false;
}
private int getOperaterGrade(char operater){
int grade = 0;
switch (operater){
case '*' : case '/' : case '%':
grade = 2;
break;
case '+' : case '-' :
grade = 1;
break;
case '(' :
grade = 0;
break;
}
return grade;
}
private void clearStack(){
char token;
while(!stack.empty()){
token = (Character)stack.pop();
inputToPostfix += token;
}
}
}
작성하다가 힘이 빠져서 코드가 정리가 안된 부분도 많이 있을것 같습니다. 잘 걸러서 참고해주세요!
문제 풀면서 막혔던 부분은
1. if else 조건을 줄 때 무슨조건을 먼저 검사할 것인지
2. Stack에 담을 객체의 타입 - 코드를 보시면 처음에 스택 하나로 postfix로 변환시에는 Char형을 넣어 사용하고 그후 계산을 할때는 Integer 형을 사용하기 때문에 두개를 변환하는 과정 등을 신경써야 했습니다.
3. while문의 종료 조건 - 반복문의 종료조건을 잘 확인하고 걸어야 했습니다.
4. 메소드를 나눌 단위 - 이 부분이 제일 어려웠습니다. 결국 나누다가 포기했지요... 잘게 쪼갤 수록 오히려 조건문이 더 많아지고 복잡해지는 느낌이 들었습니다.
'Study' 카테고리의 다른 글
(JAVA) Java DFS 구현 Java dfs ArrayList (0) | 2019.03.16 |
---|---|
(Java Greedy) 문자열안에 포함된 가장 긴 팰린드롬(palindrome)문자열 (0) | 2019.03.15 |
면접대비 용어정리 (0) | 2019.02.11 |
(딥러닝) 나는 Java가 주언어인데, 파이썬? 텐서플로우? (0) | 2019.02.11 |
Docker란 무엇인가? Docker를 사용하는 이유/동작방식 (0) | 2019.01.29 |
댓글