백준 Words

KIMYEONGJUN·4일 전
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

Input will consist of a number of lines, each containing up to 250 characters.
Words will be separated by single spaces, i.e. not by tabs, double spaces or other characters.
Words may be of any length. Input will be terminated by a line containing a single #.

Output will consist of one line for each line of input.
In the output line, each word (as defined in paragraph 2 above) in the input line will be reversed.

내가 이 문제를 보고 생각해본 부분

입력과 출력을 위한 도구 준비 (BufferedReader, BufferedWriter)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
이 부분은 키보드 입력(표준 입력 System.in)을 더 빠르고 효율적으로 읽기 위해 BufferedReader를 사용하는 설정이다. 
InputStreamReader는 바이트 스트림을 문자 스트림으로 변환해주고, BufferedReader는 문자들을 한꺼번에 모아서 읽어 처리하기 때문에 한 글자씩 읽는 것보다 훨씬 빠르다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
프로그램의 출력(표준 출력 System.out)을 효율적으로 쓰기 위해 BufferedWriter를 사용한다.
OutputStreamWriter는 문자 스트림을 바이트 스트림으로 변환해주고, BufferedWriter는 출력할 문자들을 내부 버퍼에 모아두었다가 한 번에 내보내기 때문에 출력 작업이 많을 때 성능 이점을 얻을 수 있다.
한 줄씩 입력받아 처리하는 반복문
String line;
입력으로 들어오는 각 줄의 내용을 저장할 변수 line을 선언한다.
while ((line = br.readLine()) != null && !line.equals("#")) { ... }
이 while 반복문은 문제에서 요구하는 대로, 입력이 종료될 때까지 각 줄을 읽어 처리하는 핵심 로직이다.
line = br.readLine(): BufferedReader를 이용해 한 줄을 읽어 line 변수에 할당한다.
line != null: readLine() 메서드는 더 이상 읽을 줄이 없으면 null을 반환한다. 
null이 아니라는 것은 아직 읽을 내용이 있다는 뜻이다.
!line.equals("#"): 문제에서 입력의 마지막 줄은 #이라고 명시했다. 
따라서 읽은 줄이 #이 아닐 때만 내부 코드를 실행하도록 조건문을 넣은 것이다.
이 두 조건을 모두 만족하는 동안, 즉 #이 아닌 새로운 줄이 계속해서 입력되는 동안 반복문 내부의 코드가 실행된다.
단어를 분리하고 최종 결과를 만드는 준비
String[] words = line.split(" ");
현재 읽어온 한 줄의 문자열 line을 split(" ") 메서드를 사용해서 공백(" ")을 기준으로 나눈다. 
이렇게 나누어진 각각의 조각(단어)들은 String 배열 words에 저장된다. 
예를 들어, "teG ydaer rof"라는 줄이 들어오면 words 배열에는 ["teG", "ydaer", "rof"] 이렇게 세 개의 단어가 들어가게 된다.
StringBuilder sb = new StringBuilder();
각 줄의 처리 결과를 효율적으로 만들기 위해 StringBuilder 객체 sb를 선언한다. 
String 객체는 내용을 변경할 때마다 새로운 객체를 생성하는 반면, StringBuilder는 기존 객체의 내용을 바로 수정할 수 있어 문자열을 여러 번 수정하거나 추가할 때 훨씬 빠르고 메모리 사용도 효율적이다.
각 단어를 뒤집고 결과 문자열에 추가
for (int i = 0; i < words.length; i++) { ... }
words 배열에 저장된 모든 단어를 처음부터 끝까지 순서대로 반복하면서 처리하기 위한 for 반복문이다.
StringBuilder reversedWord = new StringBuilder(words[i]).reverse();
words 배열에서 현재 차례인 단어(words[i])를 가져와서 새로운 StringBuilder 객체로 만든다. 
그리고 이 StringBuilder의 .reverse() 메서드를 호출하여 단어의 문자 순서를 완전히 뒤집는다. 
예를 들어, "teG"는 "Get"으로, ".tsetnoC"는 "Contest."로 바뀌게 되는 것이다.
sb.append(reversedWord);
방금 뒤집은 단어(reversedWord)를 최종 결과물을 만들고 있는 StringBuilder sb에 추가한다.
if (i < words.length - 1) { sb.append(" "); }
이 조건문은 각 단어 뒤에 공백을 추가할지 말지를 결정한다. 
배열의 마지막 단어 뒤에는 공백을 붙이면 안 되기 때문에, i가 words.length - 1 (마지막 인덱스)보다 작을 때만 (즉, 마지막 단어가 아닐 때만) 공백을 추가하도록 한다.
한 줄의 결과 출력
bw.write(sb.toString());
현재 줄의 모든 단어 처리가 끝나면, sb.toString()을 호출하여 StringBuilder에 담겨있던 최종 문자열을 BufferedWriter bw에 쓴다.
bw.newLine();
그리고 한 줄의 출력이 끝났으므로 bw.newLine()을 호출하여 다음 출력을 위해 줄바꿈 문자를 추가한다.
자원 정리
br.close();
모든 입력을 다 읽었으므로 BufferedReader를 닫아서 입출력 자원을 해제한다.
bw.flush();
BufferedWriter는 내부 버퍼에 데이터를 모아두기 때문에, 프로그램을 종료하기 전에 flush()를 호출하여 버퍼에 남아있는 모든 내용을 실제로 출력 스트림으로 내보내도록 해야 한다.
이 줄이 없으면 마지막 출력 내용이 보이지 않을 수도 있다.
bw.close();
BufferedWriter까지 모두 사용했으니 닫아서 출력 자원도 해제한다.

코드로 구현

package baekjoon.baekjoon_32;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;

// 백준 4072번 문제
public class Main1272 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        String line;
        // 입력이 '#'으로 끝날 때까지 반복합니다.
        while ((line = br.readLine()) != null && !line.equals("#")) {
            // 각 줄을 공백 기준으로 단어로 분리합니다.
            String[] words = line.split(" ");
            StringBuilder sb = new StringBuilder();

            // 분리된 각 단어를 처리합니다.
            for (int i = 0; i < words.length; i++) {
                // 단어를 StringBuilder로 만들어서 뒤집습니다.
                StringBuilder reversedWord = new StringBuilder(words[i]).reverse();
                sb.append(reversedWord);

                // 마지막 단어가 아니면 뒤에 공백을 추가합니다.
                if (i < words.length - 1) {
                    sb.append(" ");
                }
            }
            // 한 줄의 결과물을 버퍼에 쓰고 줄바꿈합니다.
            bw.write(sb.toString());
            bw.newLine();
        }

        br.close();
        bw.flush(); // 버퍼에 남아있는 내용을 모두 출력합니다.
        bw.close();
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글