문제 이름 : 별 찍기 - 2
문제
첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N
번째 줄에는 별 N
개를 찍는 문제
하지만, 오른쪽을 기준으로 정렬한 별(예제 참고) 를 출력하시오.
입력
첫째 줄에 N
(1 <= N
<= 100)이 주어진다.
출력
첫째 줄부터 N
번째 줄까지 차례대로 별을 출력한다.
예제 입력 1
5
예제 출력 1
*
**
***
****
*****
바로 이전의 문제는 왼쪽부터 별을 출력하는 간단한 문제였지만,
이번에는 오른쪽부터 별을 출력하는 문제로 변모했다.
그렇다면, 먼저 이에 대해 생각해 보아야 한다.
빈 칸 또한 출력되어야 한다.
빈 칸이 존재하지 않았다면, 별이 하나가 있음에도 불구하고, 오른쪽 열에 정렬 될 수 없다는 의미이다.
우리는 이러한 점에 주목해야 한다.
그렇다면, 어떻게 오른쪽에 별을 정렬시킬 것인가?
필자가 생각나는 몇 가지 방식들이 있는데,
- 이중 중첩 반복문의 조건에 따라 빈 칸을 출력할지, 별 을 출력할지 결정한다.
N
입력 시 각 반복마다N
길이의 char 배열을 생성하여 거꾸로 별을 입력하고, 이를 출력한다.- 이중 중첩 반복문을 완벽하게
N * N
형태로 만들고,String
문자열 객체를 생성한다.
이후 별을 처음에 바로 넣고, 나머지 인덱스에는 빈 칸을 채운다.
그리고 나서 문자열을reverse
거꾸로 만든 후 출력한다.
오랜만에 돌아와서 문자열을 다루며 여러 가지 방식이 떠오르는데, 이게 바로 진정한 학습의 효과가 아닌가 생각된다.
기분이 좋으므로 3 개의 방식을 전부 써 보겠다.
가장 중요한 것은, 어떻게 오른쪽 정렬을 시킬 것인가 이다.
Answer 1 - 이중 중첩 반복문의 조건으로 오른쪽 정렬
import java.util.*;
import java.io.*;
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 = 0; i < N; i++) {
for(int j = 0; j < N - i - 1; j++) {
System.out.print(" ");
}
for(int j = N - i - 1; j < N; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
사실, 이 문제를 풀면서 String
문자열 인스턴스를 사용하지 않으면서 불편하게 만들어 보았다.
독자들에게 객체를 사용한 관심사 분리가 얼마나 편리한지 바로 직후 풀이에서 보여주기 위함이다.
그렇다면, 내가 작성한 코드를 살펴보자.
첫 번째로, for(int i = 0; i < N; i++){
를 작성하며 중첩 반복문의 시작을 알렸다.
하지만, 그 다음에는 반복문이 두 번 나왔다. 필자가 무슨 생각을 해서 이런 난해한 두 반복문이 나왔는지 설명 해 보겠다.
거의 처음 단락에서, 나는 빈 칸(공백) 도 출력되어야 한다고 했다.
문자열 출력이 마치 만능처럼, 중력을 사용하는 것처럼 정렬을 해 줄수 있는 도구가 아니다.
따라서, 특정 조건까지 빈 칸 을 출력하고, 이후에 특정 조건까지 별 을 출력하게 한 것이다.
이러한 특정 조건은 N - i - 1
을 알면 코드의 의미를 알 것이다.
먼저, 별(*
)은 첫 번째부터 바로 등장한다는 것을 알아야 한다.
만약에 내가 N - i
라고 조건을 단정지었다면, *
은 첫 번째 줄부터 등장하지 않고, 두 번째부터 등장한다.
그리고 입력값 N
이 5
라면, 마지막 줄은 *****
처럼 출력되지 않고, ****
로 4 개만 출력되고 끝난다.
따라서, 이러한 문제를 해결하기 위해 N - i
에 추가로 - 1
을 붙여서 처음부터 별이 나오게 한 것이다.
혹시 왜 N - i
인지 궁금하다면, 공백과 별 숫자의 조절 에 신경써서 읽으면 이해 될 것이다.
Answer 2 - char 배열을 사용하여 거꾸로 출력
import java.util.*;
import java.io.*;
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 = 0; i < N; i++) {
// 결과 출력에 사용될 chStr 배열 생성
char[] chStr = new char[N];
// Arrays.fill(chStr, ' ') 로 대체 가능함. 모든 요소를 빈칸으로 초기화
for(int j = 0; j < chStr.length; j++)
chStr[j] = ' ';
// '*'을 왼쪽 정렬로 만들어버린다.
for(int j = 0; j <= i; j++) {
chStr[j] = '*';
}
// 맨 마지막 인덱스부터 조회하여, 출력되면 오른쪽 정렬로 만듬.
for(int j = chStr.length - 1; j >= 0; j--)
System.out.print(chStr[j]);
System.out.println();
}
}
}
char
배열을 생성하여 초기화하고, 이를 순서대로 *
로 채워넣는 것은 왼쪽 정렬로, 문제와는 원래 맞지 않다.
하지만, 마지막에 이를 마지막 인덱스에서부터 조회하여, 오른쪽 정렬로 만드는 방식이다.
복잡하게 별과 공백의 수 조절 에 신경쓰지 않고, 배열을 이용하여 쉽게 만드는 방식이다.
Answer 3 - String 을 이용한 오른쪽 정렬
import java.util.*;
import java.io.*;
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 = 0; i < N; i++) {
String str = "";
for(int j = 0; j <= i; j++)
str += "*";
for(int j = i + 1; j < N; j++)
str += " ";
String resultStr = "";
for(int j = str.length() - 1; j >= 0; j--)
resultStr += str.charAt(j);
System.out.println(resultStr);
}
}
}
이번엔 String
객체를 사용하여 결과물을 출력하는 방식이다.
Answer 2 와 같이 왼쪽 정렬이 되도록 만들고,
String
객체 내부의 문자를 .charAt(index)
로 거꾸로 접근하여
결과물을 출력할 resultStr
에 적층 해 나가는 방식이다.
char
배열은 +
연산이 불가능하다. 기본적으로 사이즈가 정해진 배열 이기 때문이다.
하지만, String
객체는 +
연산으로 내용을 이어서 작성 할 수 있다.
String
은 String
을 더할 수도 있지만, char
타입의 변수도 더할 수 있다.
따라서, 거꾸로 인덱스를 접근함으로서 올바른 결과물을 출력 할 수 있다.
'백준-단계별로 풀어보기 > 3-반복문' 카테고리의 다른 글
백준 10952 - A + B - 5 (0) | 2024.08.07 |
---|---|
백준 2739 - 구구단 (1) | 2024.07.31 |