
내가 생각했을때 문제에서 원하는부분
The input consists of one or more strings, each 1–79 characters long and on a line by itself, followed by a line containing only "#" that signals the end of the input.
The character "#" is used only as an end-of-input marker and will not appear anywhere else in the input.
A string may contain spaces, but not at the beginning or end of the string, and there will never be two or more consecutive spaces.
For each input string, replace every occurrence of a reserved character in the table above by its percent-encoding, exactly as shown, and output the resulting string on a line by itself.
Note that the percent-encoding for an asterisk is %2a (with a lowercase "a") rather than %2A (with an uppercase "A").
내가 이 문제를 보고 생각해본 부분
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));:
표준 입력(System.in)으로부터 데이터를 읽어오기 위해 BufferedReader 객체를 생성한다.
InputStreamReader는 System.in(바이트 스트림)을 BufferedReader가 읽을 수 있는 문자 스트림으로 변환해 준다.
이렇게 하면 한 줄씩 텍스트를 효율적으로 읽을 수 있다.
StringBuilder resultBuilder = new StringBuilder();:
최종적으로 모든 인코딩된 문자열들을 모아서 한 번에 출력하기 위해 StringBuilder를 선언한다.
StringBuilder는 문자열을 반복적으로 추가하거나 수정할 때 String 객체보다 훨씬 효율적이다.
String line;:
BufferedReader로 한 줄씩 읽어온 문자열을 저장할 변수 line을 선언한다.
while (!(line = br.readLine()).equals("#")):
이 while 루프는 입력의 끝을 알리는 "#" 문자가 나타날 때까지 계속 반복된다.
br.readLine(): 표준 입력에서 한 줄을 읽어와 line 변수에 할당하다.
line = br.readLine(): 할당된 line 변수의 값(String 객체)이
.equals("#"): 문자열 "#"과 동일한지 비교한다.
!: equals("#")의 결과가 false일 때("#"이 아니면) 루프를 계속 진행한다.
즉, #을 만나면 루프가 종료된다.
StringBuilder encodedLineBuilder = new StringBuilder();:
각 입력 line마다 해당 줄을 인코딩한 결과를 임시로 저장할 StringBuilder를 새로 생성한다.
이렇게 하면 각 줄의 인코딩이 독립적으로 이루어지며 효율적으로 문자열을 구성할 수 있다.
for (int i = 0; i < line.length(); i++) { ... }:
현재 읽어온 line 문자열의 모든 문자를 하나씩 순회한다.
char ch = line.charAt(i);:
현재 순회 중인 인덱스 i에 해당하는 문자를 ch 변수에 저장한다.
switch (ch) { ... }:
현재 문자 ch가 특정 예약 문자인지 확인하고, 그에 맞는 Percent-Encoding 값으로 변환하는 부분이다.
case ' ': 만약 ch가 공백이면 encodedLineBuilder에 "%20"을 추가한다.
case '!: 만약 ch가 느낌표이면 encodedLineBuilder에 "%21"을 추가한다.
case '$':, case '%':, case '(':, case ')': 등 다른 예약 문자들도 같은 방식으로 처리된다.
case '*':: 별표의 경우, %2a (소문자 'a')로 인코딩하도록 명시적으로 처리된다.
default:: 위에 나열된 예약 문자가 아닌 경우에는 ch 문자를 그대로 encodedLineBuilder에 추가한다.
resultBuilder.append(encodedLineBuilder.toString()).append('\n');:
한 줄에 대한 모든 문자 인코딩이 끝나면, encodedLineBuilder에 저장된 결과(toString()으로 String으로 변환)를 resultBuilder에 추가한다.
append('\n'): 각 줄의 결과 뒤에는 새 줄 문자를 추가하여 다음 인코딩된 문자열이 다음 줄에 출력되도록 한다.
System.out.print(resultBuilder.toString());:
while 루프가 종료되면("#"을 만나면), resultBuilder에 모아진 모든 인코딩된 문자열을 한 번에 표준 출력(System.out)으로 출력한다.
이렇게 하면 여러 번의 출력으로 인한 성능 저하를 방지할 수 있다.
print를 사용하여 마지막에 불필요한 추가 개행은 하지 않다.
br.close();:
모든 입력을 다 읽고 나면 BufferedReader 객체가 사용하던 자원(파일 스트림 등)을 해제한다.
코드로 구현
package baekjoon.baekjoon_32;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
// 백준 4606번 문제
public class Main1261 {
public static void main(String[] args) throws IOException {
// 입력을 효율적으로 읽기 위해 BufferedReader를 사용합니다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 출력 효율을 위해 StringBuilder를 사용합니다.
StringBuilder resultBuilder = new StringBuilder();
String line;
// 입력이 "#" 단독인 줄이 아니면 계속 반복합니다.
while (!(line = br.readLine()).equals("#")) {
// 각 입력 줄에 대한 인코딩 결과를 저장할 StringBuilder를 생성합니다.
StringBuilder encodedLineBuilder = new StringBuilder();
// 현재 입력 줄의 각 문자를 순회합니다.
for (int i = 0; i < line.length(); i++) {
char ch = line.charAt(i); // 현재 문자
// switch 문을 사용하여 예약 문자를 확인하고 Percent-Encoding을 적용합니다.
switch (ch) {
case ' ':
encodedLineBuilder.append("%20");
break;
case '!':
encodedLineBuilder.append("%21");
break;
case '$':
encodedLineBuilder.append("%24");
break;
case '%':
encodedLineBuilder.append("%25");
break;
case '(':
encodedLineBuilder.append("%28");
break;
case ')':
encodedLineBuilder.append("%29");
break;
case '*':
encodedLineBuilder.append("%2a"); // 주의: 소문자 'a'
break;
default: // 예약 문자가 아니면 그대로 추가합니다.
encodedLineBuilder.append(ch);
break;
}
}
// 한 줄의 인코딩이 완료되면 결과 StringBuilder에 추가하고 새 줄 문자를 붙입니다.
resultBuilder.append(encodedLineBuilder.toString()).append('\n');
}
// 최종 결과를 한 번에 출력합니다.
System.out.print(resultBuilder.toString());
// BufferedReader를 닫아 자원을 해제합니다.
br.close();
}
}
코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.