본문 바로가기
공부/알고리즘

[백준]17413_단어 뒤집기 2_Java 풀이

by happyeuni 2023. 2. 4.

17413번: 단어 뒤집기 2

 

풀이

첫 풀이

  1. 문자열을 “ “ 띄어쓰기 단위로 잘라서 (StringTokenizer 사용) → word 단위로 만듬
  2. 띄어쓰기 없이 잘라진 것에서 그 길이만큼의 반복문 안에서
    1. tag 안에 있는 것인지 밖에 있는 것인지 구별하여
    2. tagBuilder나 reverse라는 스택 안에 넣어주는 방식으로 풀이
  • 자세한 사항// > 로 끝났을 때 tag가 끝난 것이기 때문에 tagBuilder에 쌓인 값 answer에 넣어주기
    package etc;
    
    import java.io.*;
    import java.util.*;
    
    public class Main_17413 {
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String S = br.readLine();
            StringTokenizer st = new StringTokenizer(S);
    
            StringBuilder answer = new StringBuilder(); // 전체 정답 문장
            StringBuilder tagBuilder = new StringBuilder(); // 올바르게 들어갈 <> tag안의 문장. 띄어쓰기 포함 가능해서 다음 word에 있는 값이 있을 수도 있음
            boolean tag = false; // 현재 tag가 열려있는지 여부. true의 값이면 > 가 아직 없음
            while(st.hasMoreTokens()){
                String word = st.nextToken();
    
                Stack<Character> reverse = new Stack<>(); // 거꾸로 될 문장
    
                for (int i = 0; i < word.length(); i++) {
                    if(word.charAt(i) == '<'){
                        tag = true;
                        int s = reverse.size();
                        for (int j = 0; j < s; j++) {
                            answer.append(reverse.pop());
                        }
    
                    } else if (word.charAt(i) == '>') {
                        tag = false;
                        tagBuilder.append(word.charAt(i));
                        answer.append(tagBuilder);
                        tagBuilder = new StringBuilder(); // 비우기 이렇게 가능?
                        continue;
                    }
                    if(tag){
                        tagBuilder.append(word.charAt(i));
                    }else{
                        reverse.push(word.charAt(i));
                    }
    
                }
                if(tag){ // tag가 진행중인데 한 word가 끝난 경우는 사이에 띄어쓰기가 있는 것이므로 넣어주기
                    tagBuilder.append(" ");
                }
                int s = reverse.size();
                for (int i = 0; i < s; i++) {
                    answer.append(reverse.pop());
                }
                if(answer.length()!=0 && !tag && st.hasMoreTokens()){
                    answer.append(" ");
                }
            }
            System.out.println(answer.toString());
        }
    }
    
  • // < 나 >는 아니지만 tag안에 있는 경우는 tagBuilder에 넣기 // < 나 >는 아니지만 tag밖에 있는 경우는 reverse에 넣기
  • // < 로 시작했을 때 그 이전에 reverse 스택에 쌓인 것 answer에 넣어주기 여기서는 " " 를 넣지 않음(태그와 단어 사이에 띄어쓰기가 없음)

→ 계속 ‘출력 형식이 잘못되었습니다’ 라고 떠서 반례를 찾아 헤매다

공백이 <> 태그안에 여러개가 있는 경우를 생각함..

태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.

이 문장에서 보면 태그 안은 단어가 아니기 때문에 공백이 여러번 들어갈 수 도 있다. ㅎ……………………..

+진짜 바보인가..문제에 있는 예제 7번에 그런 케이스도 말해줬었는데 못봄..

→ 처음부터 다시 접근해야함^^

두번째 풀이

문자열 길이 S.length() 만큼 for문을 돌면서

  • < > 안은 tagBuilder 에 넣어서
    • answer에 추가해준다.
  • < > 밖은 reverse 스택에 넣어서 - 공백이 나올 때 까
    • answer에 추가해준다.

코드

package etc;

import java.io.*;
import java.util.*;

public class Main_17413 {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String S = br.readLine();

        StringBuilder answer = new StringBuilder(); // 전체 정답 문장
        StringBuilder tagBuilder = new StringBuilder(); // 올바르게 들어갈 <> tag안의 문장. 띄어쓰기 포함 가능해서 다음 word에 있는 값이 있을 수도 있음
        boolean tag = false; // 현재 tag가 열려있는지 여부. true의 값이면 > 가 아직 없음
        Stack<Character> reverse = new Stack<>(); // 거꾸로 될 문장

        for (int i = 0; i < S.length(); i++) {
            if(S.charAt(i) == '<') {
                tag = true;
                while (!reverse.isEmpty()) {
                    answer.append(reverse.pop());
                }
            } else if (S.charAt(i) == '>') {
                tag = false;
                tagBuilder.append(S.charAt(i));
                answer.append(tagBuilder);
                tagBuilder = new StringBuilder();
                continue;
            }
            if(tag) {
                tagBuilder.append(S.charAt(i));
            } else {
                if(S.charAt(i) == ' ' || i == S.length()-1) {
                    if(i == S.length()-1){
                        reverse.push(S.charAt(i));
                    }
                    while (!reverse.isEmpty()) {
                        answer.append(reverse.pop());
                    }
                    answer.append(" ");
                } else {
                    reverse.push(S.charAt(i));
                }
            }
        }

        System.out.println(answer);
    }
}

참고

  • 참고 코드
    import java.util.Scanner;
    
    public class Main {
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		String s = sc.nextLine();
    		StringBuilder sb = new StringBuilder();
    		int i = 0;
    		int j = i;
    		while(i<s.length()) {
    			if(s.charAt(i)=='<') {
    				j = i;
    				while(i<s.length()&&s.charAt(i)!='>')i++;
    				sb.append(s.substring(j, ++i));
    			}else if(s.charAt(i)!=' ') {
    				j = i++;
    				while(i<s.length() &&s.charAt(i)!=' '&&s.charAt(i)!='<')i++;
    				for (int k = i-1; k >= j; k--) {
    					sb.append(s.charAt(k));
    				}
    			}else if(s.charAt(i++)==' ') sb.append(" ");
    
    		}
    		System.out.println(sb);
    	}
    }
    
  •  
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.nextLine();
		StringBuilder sb = new StringBuilder();
		int i = 0;
		int j = i;
		while(i<s.length()) {
			if(s.charAt(i)=='<') {
				j = i;
				while(i<s.length()&&s.charAt(i)!='>')i++;
				sb.append(s.substring(j, ++i));
			}else if(s.charAt(i)!=' ') {
				j = i++;
				while(i<s.length() &&s.charAt(i)!=' '&&s.charAt(i)!='<')i++;
				for (int k = i-1; k >= j; k--) {
					sb.append(s.charAt(k));
				}
			}else if(s.charAt(i++)==' ') sb.append(" ");

		}
		System.out.println(sb);
	}
}

 

댓글