seops

BOJ_1406_에디터_코드 질문 본문

알고리즘 스터디 (종료)/(질문) 공지사항 참조

BOJ_1406_에디터_코드 질문

seops 2018. 1. 26. 00:07



 최근에, 알고리즘을 공부하는 친구가 '에디터' 문제(https://www.acmicpc.net/problem/1406)를 물어봤었는데... 가입하지 않으면 블로그에 질문을 올릴 수 없다는 사실을 알게 되었습니다. 앞으로 질문을 하는 게시판에 대한 구성을 어떻게 할지, 다시 한번 생각해봐야될 것 같습니다. 그래도 일단, 해당 문제에 대한 질문부터 알아보도록 하겠습니다.


"문제에 제시된 Test-Case를 모두 돌려보면

 맞다고 나오는데... 제출하면 틀렸다고 나오네..."


 ->  문제에서 제시된 Test-Case는 극히 일부에 해당된다고 생각하면됩니다. 특히, 제 경험상 모든 기업에서 pre-test 진행시, 자신의 코드가 정확히 100% 맞는지, 아니면 틀린지는 알려주지 않습니다. 단지, 몇가지 test-case를 통해 테스트(?)할 수 있는 정도? 그러므로, 문제를 다 풀었다고 생각해도 틀릴 수도 있다는 사실을 명심하는 것이 좋습니다.



"분명히 코드는 맞는 것 같은데, 틀린 부분을 못찾겠어!"


import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Stack;

import java.util.StringTokenizer;

   

   public class Edit{

      

      public static void main(String argv[]) throws IOException

      {

         

         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

         

         Stack<String> stack1 = new Stack<String>();

         Stack<String> stack2 = new Stack<String>();

         int num;

         String str = br.readLine();

         

         StringTokenizer c = new StringTokenizer(str);

         

         while(c.hasMoreTokens())   

            stack1.push(c.nextToken());

         

         num = Integer.parseInt(br.readLine());

         

         for(int i=0; i<num; i++)

         {

            String res = br.readLine();

            StringTokenizer ne = new StringTokenizer(res, " ");

               

            String cmd = ne.nextToken();

            

            if(cmd.equals("P"))

            {

               stack1.push(ne.nextToken());               

            }

            else if(cmd.equals("L"))

            {

                  if(!stack1.empty())

                     stack2.push(stack1.pop());

            }

            else if(cmd.equals("D"))

            {

               if(!stack2.empty())

               {

                  stack1.push(stack2.pop());

               }

            }

            else if(cmd.equals("B"))

            {

               

               if(!stack1.empty())

               {   

                  stack1.pop();

               }

            }

            

         }

         while(!stack1.empty()) {//stack1이 비어있지 않을 때 까지 반복

            stack2.push(stack1.pop());

         }

         StringBuilder sb = new StringBuilder();

         while(!stack2.empty())

         {

            sb.append(stack2.pop());

         }

         System.out.println(sb);

         stack1.clear();

         stack2.clear();

         

         }

   }


 저도 처음에 코드에서 문제점을 찾기가 어려웠습니다. 각각의 문자에 따른 알고리즘 또한 문제가 없었고 기존의 StringTokenizer 클래스를 이용해 본 적이 없었기 때문입니다. 따라서, StringTokenizer가 제대로 작동되는지 print 해봄으로써 문제를 찾을 수 있었습니다.


 이해를 돕기 위해, StringTokenizer의 정규식을 첨부하겠습니다.

(https://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html)


 파란색의 경우(StringTokenizer ne = new StringTokenizer(res, " ");), 입력받은 문자열 res를 공백(' ')으로 split 해줍니다. 하지만 빨간색의 경우(StringTokenizer c = new StringTokenizer(str);), 자동으로 문자열 하나하나 split 해주지 않습니다. 따라서 stack에 넣어줄때, str 문자열이 한번에 들어가는 오류를 범하게 됩니다.


 그러므로, 다음과 같이 String 클래스의 charAt() 메소드를 이용해, 문제를 해결할 수 있습니다.

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Stack;

import java.util.StringTokenizer;


public class Test {


   public static void main(String argv[]) throws IOException {


      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));


      Stack<String> stack1 = new Stack<String>();

      Stack<String> stack2 = new Stack<String>();

      int num;

      String str = br.readLine();


      StringTokenizer c = new StringTokenizer(str);

      /*

      while (c.hasMoreTokens()) {

         String a = c.nextToken();

         // 에러 발생 : string에서 char 하나하나를 꺼내지 못함

         System.out.println(a);

         stack1.push(a);

      }

      */

      for(int i = 0; i < str.length(); i++) {

         stack1.push(str.charAt(i)+"");

      }

      

      num = Integer.parseInt(br.readLine());


      for (int i = 0; i < num; i++) {

         String res = br.readLine();

         StringTokenizer ne = new StringTokenizer(res, " ");


         String cmd = ne.nextToken();

         //System.out.println(cmd);

         

         if (cmd.equals("P")) {

            stack1.push(ne.nextToken());

         } else if (cmd.equals("L")) {

            if (!stack1.isEmpty())

               stack2.push(stack1.pop());

         } else if (cmd.equals("D")) {

            if (!stack2.isEmpty()) {

               stack1.push(stack2.pop());

            }

         } else if (cmd.equals("B")) {

            if (!stack1.isEmpty()) {

               stack1.pop();

            }

         }


      }

      while (!stack1.isEmpty()) {// stack1이 비어있지 않을 때 까지 반복

         stack2.push(stack1.pop());

      }

      StringBuilder sb = new StringBuilder();

      while (!stack2.isEmpty()) {

         sb.append(stack2.pop());

      }

      System.out.println(sb);

      stack1.clear();

      stack2.clear();


   }

}


이상 질문 포스팅을 마치겠습니다. 감사합니다!

Comments