본문 바로가기
Baekjoon/[1] 자료구조

[백준] 17413번 단어 뒤집기2 JAVA (자바) 풀이

by Poorm 푸름 2023. 6. 28.

문제 17413번

 : 문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.

 : 문자열 S 규칙

  1) 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로 이루어짐

  2) 문자열의 시작과 끝은 공백이 아니다.

  3) '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.

  4) 태그 '< >' 사이의 문자열은 길이가 3 이상

  5) '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다

  6) 태그는 단어가 아니라 뒤집지 않고 태그와 다른 단어 사이에는 공백이 없다.

 

 [입력]


 : 첫째 줄에 주어지는 문자열 S

 

 [출력]


 : 첫째 줄에 문자열 S의 단어를 뒤집어서 출력

 

 [스택 연산]

 

  init()  스택을 초기화
  create()  스택을 생성
  is_empty(s)  스택이 비어있는지 검사
  is_full(s)  스택이 가득 찼는지 검사 
  push(e)  스택의 맨 위에 요소 e 추가
  pop(s)  스택의 맨 위 요소를 삭제
  peek(s)  스택의 맨 위 요소를 삭제하지 않고 반환
  top()  스택 맨 위에 있는 데이터 값 반환
  push()  스택에 데이터 삽입
  pop()  스택에서 데이터 삭제하여 반환
  isEmpty()  스택에 원소가 없으면 'True', 있으면 'False' 값 반환
  isFull()  스택에 원소가 없으면 'False', 있으면 'True' 값 반환

 

 [코드]

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        Stack<Character> stack = new Stack<>();    
        StringBuilder sb = new StringBuilder();
        boolean test = false;
        
        for(int i = 0; i<str.length(); i++){
           if(str.charAt(i) == '<'){
              while(!stack.isEmpty()){
                sb.append(stack.pop());
              }
              sb.append(str.charAt(i)); //<인 문자만 출력
              test = true;
           }
            
           else if(str.charAt(i) == '>'){
              sb.append(str.charAt(i)); //>인 문자만 출력
              test = false;
		   }
            
           else if(test == true){
              sb.append(str.charAt(i));
		   }
           
           else if( test == false){
              if(str.charAt(i) == ' '){
                 while(!stack.isEmpty()){
                    sb.append(stack.pop());
                 }
                 sb.append(str.charAt(i)); //다시 공백넣기
              }
           
           else{
              stack.push(str.charAt(i)); //숫자넣기
           }
          }
        }
        
        while(!stack.isEmpty()){
			sb.append(stack.pop()); // 거꾸로 빼기
		}
        
       System.out.println(sb);
    }
}

 

 [해설]

 :  String str = br.readLine();  첫째줄 입력받기
      
 :  Stack<Character> stack = new Stack<>();  스택 선언
      
 :  StringBuilder sb = new StringBuilder();  문자 이어서 붙일거라서 넣어주기

 :  boolean test = false;  구분하기 위해 사용
                                      기본값은 false다 
                                      < 를 만나면 true로 바꾸고
                                      > 를 만나면 false로 설정한다
                                      true 랑 false 를 구분한 기준은 그대로 출력할 때랑 거꾸로 출력할 때 차이
                                      <를 만나면 >만날 때까지는 안의 문자열의 순서가 변하지 않는다
                                      >를 만나거나 <>태그가 없을 때에는 문자를 모두 거꾸로 출력한다
    

  :  for(int i = 0; i<str.length(); i++)  str 문자 길이만큼 반복한다
           
  :  if(str.charAt(i) == '<') {
             while( !stack.isEmpty() ) { 스택이 비어 있을때까지 모두 다 빼기
                    sb.append(stack.pop()); 문장 전체가 아닌 단어별로 각각 따로 거꾸로 출력해야해서 출력하기
             }
             sb.append(str.charAt(i));  <인 문자만 출력

             test = true; <만나면 상태를 true 로 바꿔준다
      }
            
 :  else if(str.charAt(i) == '>') {
           sb.append(str.charAt(i));  >인 문자만 출력

           test = false;  > 만나면 상태 false 로 바꿔준다
    }
            
 :  else if(test == true) { < 만난 이후로는 > 만나기 전까지는 쭉 상태 true 유지

           sb.append(str.charAt(i)); 상태가 true 인 동안에는 그안의 문자열 그대로 출력
   }
         
 :  else if( test == false) {  >를 만나거나 태그 없이 기본값일 때 상태가 false 다

           if(str.charAt(i) == ' ') {  상태가 false 일때 공백을 만나면
                 while( !stack.isEmpty() ) { 
                      sb.append(stack.pop());  그 전의 것들은 다 빼기
                  }
                 sb.append(str.charAt(i));  다시 공백넣기
            }
           else { 공백이 아닐경우, 또 다른 공백을 만날 때 까지 stack에 push
                stack.push(str.charAt(i));  true일 때 sb.append(str.charAt(i)) 하지 않은 이유는

           }                                            얘는 순서대로가 아니라 거꾸로 빼야해서 바로 append로 빼주지 않고

    }                                                   일단 스택에 push 한 다음 pop으로 뺀다        


 :  while( !stack.isEmpty() ) {
         sb.append(stack.pop());  거꾸로 빼주기
    }
 

 :  System.out.println(sb); 출력하기
  

 

이제 풀어보러 갈께요 :)

 

 

 

https://www.acmicpc.net/problem/17413

 

17413번: 단어 뒤집기 2

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져

www.acmicpc.net

 

* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *