[백준] 10172번 : 개 - JAVA [자바]
https://www.acmicpc.net/problem/10172
- 문제
- 4가지 풀이 방법을 이용한다.
크게 System 클래스, BufferedReader, StringBuilder, StringBuffer 를 이용하여 풀이 할 것이다.
- 문제 풀이 전에
문제가 백준 10171 - 고양이와 매우 비슷하니 참고하면 좋을 것 같다.
위 링크의 글에서도 잠깐 언급했지만
큰 따옴표 ( " ) 나 백슬래시 ( \ ) 는 단독으로 써서 출력할 수가 없다.
그래서 이를 출력하기 위해 특정 구문을 사용하는데 이를 이스케이프 한다고 말한다.
그리고 결합된 그 문자를 Escape Sequence 라고 하는데 백슬래시 ( \ ) 와 문자 하나를 결합하여 나타낸다.
우리가 흔히 쓰는 \n \t 같은 것도 이스케이프 시퀀스다.
( 이스케이프 시퀀스 = 이스케이프 문자 = 제어문자 .. 모두 같은 말이다. )
즉, 백슬래시를 출력하려면 ( " \\ " ) 로 해줘야 백슬래시 ( \ ) 하나가 출력되며, 백슬래시 두 개를 출력하고 싶은경우 ( " \\\\ " ) 로 해주어야 2개가 출력된다.
아래 그림은 자바에서 사용하는 표준 문자열 이스케이프 리스트다.
[짤막 지식]
추가로 누가 유니코드 문자는 왜 리스트에 없냐고 하는데
유니코드는 표준 문자열 이스케이프 시퀀스과는 다르게 컴파일러가 실행되기 전에 유니코드 이스케이프가 사전처리된다.
따라서 문자열 이스케이프가 아닌 유니코드 제어 문자 (Unicode Control Characters ) 로 분류하는게 맞다.
아래 글을 참고하면 좋을 것 같다.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.3
- 풀이
- 방법 1 ( System 클래스 - 표준 입출력 )
public class Main {
public static void main(String[] args) {
System.out.println("|\\_/|");
System.out.println("|q p| /}");
System.out.println("( 0 )\"\"\"\\");
System.out.println("|\"^\"` |");
System.out.println("||_/=\\\\__|");
/* 그 외의 방법들
System.out.print(
"|\\_/|\n" +
"|q p| /}\n" +
"( 0 )\"\"\"\\\n" +
"|\"^\"` |\n" +
"||_/=\\\\__|");
System.out.printf("%s", "|\\_/|\n
|q p| /}\n
( 0 )\"\"\"\\\n
|\"^\"` |\n
||_/=\\\\__|");
*/
}
}
큰 따옴표하고 백슬래시는 위에서 말했듯이 단독으로 쓰여서 출력할 수 없으니 이스케이프 해준다.
- 방법 2
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("|\\_/|");
bw.newLine(); // 줄 구분자
bw.write("|q p| /}");
bw.newLine();
bw.write("( 0 )\"\"\"\\");
bw.newLine();
bw.write("|\"^\"` |");
bw.newLine();
bw.write("||_/=\\\\__|");
bw.flush();
bw.close();
}
}
BufferedWriter 을 쓰는 방식이다.
개행을 bw.newLine(); 대신에 각 문자열 맨 마지막에 \n 으로 개행해주어도 무방하다.
- 방법 3
public class Main {
public static void main(String[] args){
StringBuilder sb = new StringBuilder();
sb.append("|\\_/|\n");
sb.append("|q p| /}\n");
sb.append("( 0 )\"\"\"\\\n");
sb.append("|\"^\"` |\n");
sb.append("||_/=\\\\__|\n");
System.out.println(sb);
}
}
StringBuilder 를 이용하는 방법이다.
StringBuilder 는 여러 문자열을 append (확장) 시켜주는 것이기 때문에 sb에 하나의 문자열로 연결된다.
즉 sb 가 가리키는 문자열은 "|\\_/|\n|q p| /}\n( 0 )\"\"\"\\\n|\"^\"` |\n||_/=\\\\__|" 가 된다... ( 이렇게 보면 뭐가 뭔지 잘 모르겠다.. )
- 방법 4
public class Main {
public static void main(String[] args){
StringBuffer sb = new StringBuffer();
sb.append("|\\_/|\n");
sb.append("|q p| /}\n");
sb.append("( 0 )\"\"\"\\\n");
sb.append("|\"^\"` |\n");
sb.append("||_/=\\\\__|\n");
System.out.println(sb);
}
}
이것도 StringBuilder랑 똑같다. 다만 현 단계에서는 multi-thread 를 사용하지 않기 때문에 굳이 StringBuilder를 두고 속도가 상대적으로 더 느린 StringBuffer 을 사용할 필요는 없다.
- 정리
Escape Sequance (이스케이프 시퀀스) 에 대하여 좀 더 알 수 있는 문제였다고 생각한다.
필자 또한 처음에는 유니코드도 문자열 이스케이프인줄 알았는데 엄연히 따지면 다르고 컴파일 단계부터 차이가 난다는 점에서 새로 배울 수 있었다.
물론 독자분들의 현재 학습 진행상황에 따라 이러한 부분을 그냥 넘길 수도 있지만...
적어도 이런 사소한 차이라도 알고가면 어디가서 꿇리지 않고 가장 중요한 것은 나중에 개발할 때 실수를 조금이나마 덜 할 수 있다.
그래서 되도록이면 포스팅 된 글을 읽어보고 링크도 한 번 들어가서 정독해보길 권한다.
'JAVA - 백준 [BAEK JOON] > 입출력과 사칙연산' 카테고리의 다른 글
[백준] 10998번 : A×B - JAVA [자바] (0) | 2020.02.07 |
---|---|
[백준] 1001번 : A-B - JAVA [자바] (0) | 2020.02.06 |
[백준] 1000번 : A+B - JAVA [자바] (25) | 2020.02.06 |
[백준] 10171번 : 고양이 - JAVA [자바] (0) | 2020.02.02 |
[백준] 2557번 : Hello World - JAVA [자바] (12) | 2020.01.29 |