Java

Stack : 제네릭 사용

충 민 2022. 7. 18. 23:24

결과

전 글에서 만들었던 Stack 제네릭 미사용 버전에서 private Stack stack 을 클래스로 만들어서 가져왔다면

이번 제네릭을 이용한 Stack은 import java.util.Stack; 을 선언하여  만들었다 

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

public class Main {
	// stack
	private Stack<String> stack;
	// 중위 표기법으로 입력받은 계산식
	private String infix;
	// 후위 표기법의 배열
	private String []arrfix;
	// 계산 결과
	private String result;
	private int cnt;
	
	public Main() {
		stack = new Stack<>();
		infix = new String();
		result = new String();
		cnt = 0;
	}
	
	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Main my = new Main();
		
		
		System.out.println("계산할 식을 입력해주세요.");
		my.setInfix(sc.nextLine());
		
		// 변환해주기
		my.trans();
		
		System.out.println("\n후위 표기법으로 변환합니다.");
		for(int i=0;i<my.getArrPostfix().length-my.cnt;i++) {
			System.out.print(my.getArrPostfix()[i]+" ");
		}
		
		// 계산해주기
		my.cal();
		
		System.out.println("\n\n계산 결과 : "+my.getResult());
		
	}


	// 중위를 후위로 변환
	public void trans() {
		// 입력값을 공백을 기준으로 피연산자와 연산자로 구분하여 배열에 넣어주기
		String []arrInfix = infix.split(" ");
		// 괄호도 구별해주기
		cnt = 0;
		
		// 비교를 위한 문자열
		String str = new String();
		
		// 후위 표기 배열
		arrfix = new String[arrInfix.length];
		for(int i=0;i<arrInfix.length;i++) {
			arrfix[i] = new String();
		}
		
		// 중위 연산 배열을 후위 연산 배열로 바꾸어준다.
		int i, j = 0;
		for(i=0;i<arrInfix.length;i++) {
			// 연산자
			if(arrInfix[i].equals("+") || arrInfix[i].equals("-")) {
				// 스택이 비었으면
				if(stack.isEmpty()) {
					stack.push(arrInfix[i]);
				}
				// 스택에 연산자나 괄호가 있으면
				else {
					// 연산자는 "(" 가 나오기 전까지 모든 연산자를 pop하여 출력하고
					// 스택에 push한다
					while(!stack.isEmpty()) {
						str = stack.pop();
						// "("가 나오면 다시 스택에 넣고 끝내기
						if(str.equals("(")) {
							stack.push(str);
							break;
						}
						// 나온게 연산자라면
						else {
							arrfix[j] = str;
							j++;
						}
					}
					// 스택에 연산자 push
					stack.push(arrInfix[i]);
				}
			}
			// 괄호
			else if(arrInfix[i].equals("(") || arrInfix[i].equals(")")) {
				// 괄호 갯수 카운트
				cnt++;
				// 스택이 비었으면
				if(stack.isEmpty()) {
					stack.push(arrInfix[i]);
				}
				// 스택에 연산자나 괄호가 있다면
				else {
					// "("는 스택에 push한다
					// ")"는 "(" 전까지 연산자들을 pop하여 출력하고
					// "("을 pop하여 제거한다
					if(arrInfix[i].equals("(")) {
						stack.push(arrInfix[i]);
					}
					// ")"
					else {
						str="";
						// "("가 나올때 까지 연산자 출력
						while(!str.equals("(")) {
							str = stack.pop();
							arrfix[j] = str;
							j++;
						}
						// "("을 뽑았으면 제거한다.
						if(str.equals("(")) {
							j--;
						}
					}
				}
			}
			// 피연산자
			else {
				arrfix[j] = arrInfix[i];
				j++;
			}
		}
		// 모든 연산자가 스택에서 나오지 않았을 때
		if(i == arrInfix.length && !stack.isEmpty()) {
			for(int k=0;!stack.isEmpty();k++) {
				arrfix[j+k] = stack.pop();
			}
		}
		
	}
	
	// 계산기
	public void cal() {
		int i;
		for(i=0;i<arrfix.length-cnt;i++) {
			// 더하기 연산
			if(arrfix[i].equals("+")) {
				plus();
			}
			// 빼기 연산
			else if(arrfix[i].equals("-")) {
				minus();
			}
			// 피연산자
			else {
				stack.push(arrfix[i]);
			}
		}
		// 모든 계산이 끝나면 결과값 스택에서 빼기
		if(i == arrfix.length-cnt) {
			result = stack.pop();
		}
	}
	
	// 더하기
	public void plus() {
		int num1,num2;
		num1 = Integer.parseInt(stack.pop());
		num2 = Integer.parseInt(stack.pop());
		
		result = Integer.toString((num1+num2));
		stack.push(result);
	}
	// 뺴기
	public void minus() {
		int num1, num2;
		num1 = Integer.parseInt(stack.pop());
		num2 = Integer.parseInt(stack.pop());
		
		result = Integer.toString((num2-num1));
		stack.push(result);
	}
	
	
	





	// getter/setter
	public String getResult() {
		return result;
	}
	public String getInfix() {
		return infix;
	}
	public void setInfix(String infix) {
		this.infix = infix;
	}
	public String[] getArrPostfix() {
		return arrfix;
	}
}