Bamboo is coming

[210403] 백준 10828번 스택 문제 오류 해결 java 본문

Daily life/Development vlog

[210403] 백준 10828번 스택 문제 오류 해결 java

twenty 2022. 1. 6. 16:09

 

<최종 코드>

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.IOException;

public class stackProcess {
	public ArrayList<Integer> stack = new ArrayList<>();
	
	public void pushX(int x) {
		stack.add(x);
	}
	
	public void pop() { 
		if (size()!=0) {
			System.out.println(stack.get(size()-1));
			stack.remove(size()-1);
		}
		else {
			System.out.println(-1);
		}
		//스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 
		//만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
	}
	
	public int size() {
		return stack.size();
		//System.out.println(stack.length);
		//스택에 들어있는 정수의 개수를 출력한다.
	}
	
	public int empty() {
		if (size()==0){
			return 1;
		}
		else {
			return 0;
		}
		//스택이 비어있으면 1, 아니면 0을 출력한다.
	}
	
	public int top() {
		int y;
		if (empty()!=1) {
			y = stack.get(size()-1);
			return y;
		}
		else {
			return -1;
		}
		//스택의 가장 위에 있는 정수를 출력한다. 
		//만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		stackProcess sp = new stackProcess();    //함수 호출하기 위해 객체 생성
		
		int count = Integer.parseInt(br.readLine());
		
		for (int i = 0; i<count;i++) {
			String temp = br.readLine();
			StringTokenizer st = new StringTokenizer(temp);
			
			while (st.hasMoreTokens()) {
				String order = st.nextToken();
				if (order.equals("push")) {
					int num = Integer.parseInt(st.nextToken());
					sp.pushX(num);
				}
				if (order.equals("pop")) {
					sp.pop();
				}
				if (order.equals("size")) {
					System.out.println(sp.size());
				}
				if (order.equals("empty")) {
					System.out.println(sp.empty());
				}
				if (order.equals("top")) {
					System.out.println(sp.top());
				}
			}
		}	
	}
}
 

<오류 코드>

(생략)
   public static void main(String[] args) throws IOException {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      StringTokenizer st = new StringTokenizer(br.readLine());
      err_10828 sp = new err_10828();
      
      int count = Integer.parseInt(br.readLine());
      for (int i = 0; i<count;i++) {
         String order = st.nextToken();
         if (order.equals("push")) {
            int num = Integer.parseInt(st.nextToken(order));
            sp.pushX(num);
(후략)
 

<결과>

<입력>
3
push
<출력>
Exception in thread "main" java.lang.NumberFormatException: For input string: "push"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at err_10828.main(err_10828.java:61)
 
// 문제의 61번 라인    
  int count = Integer.parseInt(br.readLine());
 

코드의 문제는 StringTokenizer st = new StringTokenizer(br.readLine());으로 받아서 nextToken을 사용한 거였는데,

 

Stringtokenizer는 문자열을 받아서 공백 또는 탭을 기본 구분자로 문자열을 나눠주는 클래스이다. 그런데 st(readLine)으로 객체를 생성하고 또 다시 객체를 호출해서 nexttoken으로 다음 토큰을 찾으니 오류가 나는 거였다. 입력은 push 1 이어서 stringTokenizer가 돌려주는 값은 {push,1}인데 다음 토큰인 1을 string에 넣으려니 계속 오류가 나는거다!!!!!!!! st에는 push가 들어가고 order에는1을 넣으려는 상황.

 

그래서 명령을 readLine으로 받는 String 변수를 만들고 그 변수를 StringTokenizer에 전달해서 객체를 만들었다. 그 객체가 토큰이 있는지 확인해서 NoSuchElementException 에러를 방지한다. 그리고 나서 nextToken으로 String 명령어를 받는다. 이 중에 별도의 숫자 명령어가 필요한 건 push 뿐이니까 push 실행 조건 내에서 int 명령어를 nextToken으로 다시 받아서 함수를 전달한다.


			// test1
//			String order = st.nextToken();
//			System.out.println(order);
//			while (st.hasMoreTokens()) {
//				String two = st.nextToken();
//				System.out.println(two);
//			}
 

부분 부분 테스트라인을 입력하며 처음부터 훑었는데 for문의 조건문이 i<1일때는 push 명령이 실행되다가 또 i<2가 되니까 오류가 나는거다.

그래서 push라는 명령이 잘 들어가는지 print해서 확인해봤고 두 번째 숫자도 명령이 잘 들어가는지 확인해봤는데 출력도 안 하고 61번 오류만 계속 띄우길래 nextToken을 포기하기로 했다.

<입력>
push
1
<출력>
push
 
<입력>
push 1
push 2
<출력>
Exception in thread "main" java.lang.NumberFormatException: For input string: "push 2"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at stackProcess.main(stackProcess.java:61)
 

그래서 구글링을 해보다가 입력만 받고 출력을 안하는게 이상해서 st.nextToken으로 받아보고 br.readLine으로도 받다가 StringTokenizer를 자세히 알게되면서 문제를 해결했다!

		// test
//		for (int i = 0; i<5;i++) {
//			String test = st.nextToken();
//			String test = br.readLine();
//			System.out.println(test);
//		}
 

처음에 Scanner로 풀었다가 시간초과로 나오는 바람에 잘 모르는 bufferedReader로 풀게 되었다. 그래서 시간도 오래 걸렸고 오류 해결하는 데에도 난관이 있었지만 일주일만에 해결하게 되어서 너무 뿌듯했다.

프로그래머는 에러 잡는 업무가 90%라고 하던데 해결되고 얻는 성취감은 이루 말할 수 없다.

 

참고 : https://sjs2215.tistory.com/93

https://tragramming.tistory.com/35

https://mentor75.tistory.com/entry/StringTokenizer

 

 

Comments