[BaekJoon] 2439번 - 별 찍기 - 2 (java)

1. 문제

👉 문제 바로가기

- 조건

시간 제한 메모리 제한
1초 128MB


- 문제

첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제
하지만, 오른쪽을 기준으로 정렬한 별(예제 참고)을 출력하시오.



- 입력

첫째 줄에 N(1 ≤ N ≤ 100)이 주어진다.



- 출력

첫째 줄부터 N번째 줄까지 차례대로 별을 출력한다.

- 예제

  입력      출력  
5
**
***
****
*****





2. 풀이


- 알고리즘

for 이중반복문을 사용해 첫 줄에 입력받은 값만큼 * 를 반복하는데 오른쪽 기준 정렬해서 출력한다.

for (초기식; 조건식; 증감식) {
    조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문 작성;
}


for (int i = 1; i <= N; i++) {
	for (int j = 1; j <= N; j++) {
		if(j<=N-i) System.out.print(" ");
		else System.out.print("*");
	}
	System.out.println();
}

1 행부터 N 행까지 출력을 하기 위한 가장 큰 틀의 for 반복문을 먼저 구상한다.
for ( int i = 1 ; i <= N ; i++ )

출력 예제를 보면 1 행에 공백 4개 출력 + 별 1개 출력, 2행에 3개 출력 + 별 2개 출력, …
즉, i 번째 행에는 공백이 N-i개의 출력되고, 별은 i 개가 출력되어야 한다.

i 는 행을 의미하고 j 는 열을 의미한다.
if 조건문을 사용해 공백 N-i개 이하의 열에는 " " 을 출력하고, 그 나머지는 별을 출력한다.





2개의 입력방식을 사용해서 결과를 출력한다.

  1. Scanner 클래스
  2. BufferedReader 클래스



- 1. Scanner 클래스

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
 
		int N = sc.nextInt();
		sc.close();
 
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
                if(j<=N-i) System.out.print(" ");
                else System.out.print("*");
			}
			System.out.println();
		}
	}
}

위와같이 객체를 생성할 때, Scanner(System.in) 에서 System.in 은 입력한 값을 Byte 단위로 읽는것을 뜻한다.

int형 데이터를 입력받기 위해 nextInt() 메서드를 사용한다.

이중 for문과 if 조건문을 사용해 각 줄마다 N-i 개의 공백i 개의 별을 출력한다.



[여기서 잠깐!]

Scanner에 대해 더 자세히 알고싶다면 여기 를 클릭하세요




- 2. BufferedReader 클래스 사용

2가지 출력 방식으로 문제를 풀어보고 비교해보자.



     ① StringBuilder
     ② BufferedWriter





① BufferedReader + 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());
		br.close();
 
		StringBuilder sb = new StringBuilder();
		
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				if(j<=N-i) sb.append(" ");
				else sb.append("*");
			}
			sb.append("\n");
		}
		System.out.print(sb);
	}
}

Integer.parseInt()을 사용해 readLine()으로 읽어온 String형 데이터를 int형으로 변환시켜준다.

StringBuilder 클래스는 문자열을 동적으로 조작하기 위한 클래스로, append() 를 사용해 문자열을 추가하여 새로운 문자열을 생성한다.

append() 를 위와 같이 나눠서 쓰면 타입 변환과 문자열 연결 연산이 추가적으로 발생하지 않고 StringBuilder에 직접 추가하기 때문에 보다 더 효율적이고 빠르다.





② BufferedReader + BufferedWriter

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
 
public class Main {
 
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		int N = Integer.parseInt(br.readLine());
		br.close();
		
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				if(j<=N-i) bw.write(" ");
				else bw.write("*");
			}
			bw.write("\n");
		}
		bw.flush();
		bw.close();
	}
}

BufferedWriter 클래스의 write() 메소드는 데이터를 내부 버퍼에 저장하고, flush() 메소드 를 사용해 버퍼를 비우고 데이터를 출력한다.

BufferedWriter 클래스의 write() 메소드는 단독으로 int 형 값만 넣을 경우 아스키 코드값으로 인식되기 때문에 다른 문자가 출력된다. 때문에 반드시 문자열과 int 형을 함께 넣어줘야 int 값을 제대로 출력할 수 있다.



[여기서 잠깐!]

BufferedWriter 클래스에 대해 더 알아보고 싶으면 여기를 클릭하면 된다.





3. 성능 비교

image

위에서 부터 순서대로

BufferedReader + StringBuilder
BufferedReader + BufferedWriter
Scanner

위와같이 입력 메소드와 알고리즘 구현 방법에 따라 시간이 달라질 수 있다.

입력의 경우 확실히 Scanner 보다는 BufferedReader 가 빠른 것을 볼 수 있다.

출력의 경우 BufferedWriter 보다는 StringBuilder 가 빠른 것을 볼 수 있다.
(그러나 데이터 양이 커지면 커질 수록 BufferedWriter 가 더 빠르다.)

BufferedWriter는 일반적으로 I/O 작업으로 인해 비교적 느릴 수 있다.
반면에 StringBuilder는 문자열 조작에 최적화된 클래스로, 문자열 연산은 일반적으로 메모리 상에서 수행되므로 상대적으로 빠를 수 있다.





관련 페이지

Categories:

Updated:

Leave a comment