BOJ 9093. 단어 뒤집기

1 minute read

BOJ 9093. 단어 뒤집기

www.acmicpc.net/problem/9093

문제

문장이 주어졌을 때, 단어를 모두 뒤집어서 출력하는 프로그램을 작성하시오.
단, 단어의 순서는 바꿀 수 없다.
단어는 영어 알파벳으로만 이루어져 있다.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 문장이 하나 주어진다.
단어의 길이는 최대 20, 문장의 길이는 최대 1000이다.
단어와 단어 사이에는 공백이 하나 있다.

출력

각 테스트 케이스에 대해서, 입력으로 주어진 문장의 단어를 모두 뒤집어 출력한다.

예제 입력 1 

2
I am happy today
We want to win the first prize

예제 출력 1 

I ma yppah yadot
eW tnaw ot niw eht tsrif ezirp

풀이

  • N개의 글자를 스택에 넣었다가 빼면 순서가 역순이 된다
  • 알파벳을 스택에 넣고, 공백이나 문자열의 끝이면 스택에서 모두 빼내서 역순으로 만든다
import java.util.Scanner;
import java.util.Stack;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int t = sc.nextInt();
        Stack<Character> stack = new Stack<>();
        sc.nextLine(); //sc.nextInt() 후에 \n이 남아있어서 Clear

        while (t-- > 0) {
            String input = sc.nextLine() + " ";
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < input.length(); i++) {
                char c = input.charAt(i);
                if (c == ' ') {
                    while (!stack.isEmpty()) {
                        sb.append(stack.pop());
                    }
                    sb.append(" ");
                } else {
                    stack.push(c);
                }
            }
            System.out.println(sb.toString());
        }
    }
}

Scanner의 nextInt() 메서드는 입력의 가장 마지막 개행 문자(\n)를 제거하지 않아  바로 다음 nextLine()을 호출하면 제대로 문자열을 입력받지 못하는 문제가 있다.
BufferedReader를 사용하여보자.

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

class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(bf.readLine());
        Stack<Character> stack = new Stack<Character>();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        while (num-- > 0) {
            String input = bf.readLine() + "\n";
            for (char ch : input.toCharArray()) {
                if (ch == ' ' || ch == '\n') {
                    while (!stack.isEmpty()) {
                        bw.write(stack.pop());
                    }
                    bw.write(ch); // 공백
                } else
                    stack.push(ch);
            }
        }
        bw.flush();
        return;
    }
}

Scanner는 space와 개행 문자(\n)를 경계로 인식하여 구분하는 반면
BufferedReader는 개행 문자(\n)만으로 경계를 구분하고 문자열만을 읽는다.

또한 Scanner에 비하여 상대적으로 빠른 속도의 장점이 있다.

Kotlin으로 작성하면 Stack을 사용하지 않고
split()joinToString() 그리고 reversed() 함수를 사용하여 작성할 수 있다.

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    var t = br.readLine().toInt()

    while(t-- > 0) {
        val input = br.readLine().split(" ")
        println(input.joinToString(" ") { it.reversed() })
    }
}

github.com/beomjo/algorithm-study/blob/main/BOJ/java/9093.java

github.com/beomjo/algorithm-study/blob/main/BOJ/kotlin/9093.kt