[백준] 2523번 : 별 찍기 - 13 - JAVA [자바]
https://www.acmicpc.net/problem/2523
2523번: 별 찍기 - 13
첫째 줄부터 2×N-1번째 줄까지 차례대로 별을 출력한다.
www.acmicpc.net
-
문제

문제를 유추해서 별을 찍으라고 한다.
딱히 유추할 것도 없이 보면, 숫자 N 을 입력받으면 N 까지 별을 1개씩 늘려가며 별을 찍고, 그 이후부턴 1개씩 줄여가면 찍으면 된다.
- 3가지 풀이방법을 제시한다.
Scanner 로 입력받아 연산하는 방법과 BufferedReader 로 입력받아 연산하는 방법, 두 가지 방법을 통해 풀이해보고자 한다.
또한 BufferedReader 에서 출력방법을 바꿔보며 어느 방법이 시간을 더 단축 시킬 수 있는지 한 번 보고자 한다.
- 알고리즘
먼저 N 이라는 숫자가 주어진다.
1 행부터 N 행까지 출력을 하기 위한 가장 큰 틀의 반복문을 먼저 구상한다.
for ( int i = 1; i <= N; i++)
그리고 출력을 보면 공백이 1 행에 1개 출력, 2행에 2개 출력, ...
즉, n 번째 행에는 n개의 별이 출력된다.
고로, 위의 for문 안에 for문 ( 이중for문 ) 을 작성해본다면 아래와 같을 것이다.
for ( int i = 1 ; i <= N ; i++ ){ for( int j = 0 ; j < i ; j++ ) { print("*"); } }
즉, i 번째 행에 i 개만큼 출력해주면 되는 것이다.
그리고는 각 행의 출력이 끝나면 개행(줄바꿈)을 해주어야 한다.
for ( int i = 1; i <= N; i++ ){ for( int j = 0; j < i; j++ ) { print("*"); } print('\n'); }
그러면 1 부터 N 행까지의 별 출력을 했으니 N+1 행부터 2N-1 행까지 출력도 짜야한다.
N+1 행의 별의 개수는 N-1 개가 되고, N+2 행의 별의 개수는 N-2 개가 된다.
즉 앞선 for문이 끝나고 새로 시작되는 for문을 i 행이라 할 때, i 의 첫 행은 N-1 이 된다.
for (int i = 1; i <= N; i++){ // 1 ~ N 행 for(int j = 0; j < i; j++) { print("*"); } print('\n'); } for (int i = N-1; i > 0; i--){ // N+1 ~ 2N-1 행 }
그렇기에 i 의 처음 초기값을 N-1 로 해주고 조건은 i 가 0 보다 클 때 까지만 반복하며 i 를 1개씩 감소시키는 것이다.
그리고서는 i 자체가 행의 별의 개수가 되기 때문에 이중 for 문을 통해 i 의 값만큼 반복해서 출력해주면 된다.
즉, 아래와 같이 짜면 된다.
for (int i = 1; i <= N; i++){ // 1 ~ N 행 for(int j = 0; j < i; j++) { print("*"); } print('\n'); } for (int i = N-1; i > 0; i--){ // N+1 ~ 2N-1 행 for(int j = 0; j < i; j++) { print("*"); } print('\n'); }
그럼 본격적으로 전체 코드를 보자.
- 풀이
- 방법 1
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int N = in.nextInt(); for (int i = 1; i <= N; i++) { // 1 ~ N for (int j = 0; j < i; j++) { System.out.print("*"); } System.out.println(); } for (int i = N - 1; i > 0; i--) { // N+1 ~ 2N-1 for (int j = 0; j < i; j++) { System.out.print("*"); } System.out.println(); } } }
그리고 반드시 이중 for 문 내부에 print() 를 써야한다. 무의식적으로 println() 을 쓰면 당연히 틀린다.
- 방법 2
BufferedReader 을 쓰는 방식이다.
그리고 반드시 자료형 타입을 잘 보아야 한다.
br.readLine() 은 문자열로 데이터를 읽으니 반드시 꺼내서 쓸 때 int 형으로 쓰고자 한다면 Integer.parseInt()로 String 을 int 형으로 변환시켜준다.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(br.readLine()); for (int i = 1; i <= N; i++) { // 1 ~ N for (int j = 0; j < i; j++) { System.out.print("*"); } System.out.println(); } for (int i = N - 1; i > 0; i--) { // N+1 ~ 2N-1 for (int j = 0; j < i; j++) { System.out.print("*"); } System.out.println(); } } }
위 코드를 실행하면 물론 Scanner 보다 BufferedReader 가 속도가 빠르니 시간이 단축되지만 출력 부분에서 System.out.print() 를 너무 자주 호출해주기 때문에 이 부분에서 좀 더 시간을 절약해볼 방법을 알아보자.
- 방법 3
다음 방법은 StringBuilder 을 사용하는 방법이다.
기본 입력은 BufferedReader 을 쓰되, System.out.print() 메소드를 너무 자주 출력하면 시간이 지연될 수 있다. 그래서 StringBuilder 을 통해 모든 문자열을 하나의 객체에 연결해준다음 출력을 하려 한다. 마지막에 한 번만 해주니 시간을 아낄 수 있는 방법 중 하나다.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(br.readLine()); StringBuilder sb = new StringBuilder(); for (int i = 1; i <= N; i++) { // 1 ~ N for (int j = 0; j < i; j++) { sb.append('*'); } sb.append('\n'); } for (int i = N - 1; i > 0; i--) { // N+1 ~ 2N-1 for (int j = 0; j < i; j++) { sb.append('*'); } sb.append('\n'); } System.out.println(sb); } }
- 성능 차이

위에서 부터 순서대로
채점 번호 : 18399610 - BufferedReader + StringBuilder
채점 번호 : 18399602 - BufferedReader + System.out.print
채점 번호 : 18399588 - Scanner + System.out.print
시간을 보면 BufferedReader 와 Scanner 의 성능차이 및 출력 방법에 따른 성능 차이 또한 볼 수 있다.
- 정리
보면 아주 단순한 문제다.
사실 저 for 문도 사용자가 짜기 나름이라 꼭 필자의 코드가 정답이라 할 수도 없다.
다만, 독자들이 이해하기 쉽도록 최대한 간결하게 짜려고 할 뿐이니 독자들이 코드를 보고 이해한다면야 자유롭게 짜도 무방하다.
'JAVA - 백준 [BAEK JOON] > 기타 문제' 카테고리의 다른 글
[백준] 10996번 : 별 찍기 - 21 - JAVA [자바] (2) | 2020.03.15 |
---|---|
[백준] 2446번 : 별 찍기 - 9 - JAVA [자바] (6) | 2020.03.13 |
[백준] 10039번 : 평균 점수 - JAVA [자바] (0) | 2020.03.13 |
[백준] 5543번 : 상근날드 - JAVA [자바] (0) | 2020.03.04 |
[백준] 2577번 : 숫자의 개수 - JAVA [자바] (36) | 2020.02.28 |
댓글을 사용할 수 없습니다.