학습 기록을 시작하기 앞서, 나는 뛰어난 개발자는 아니지만 꾸준한? 아니 끈질긴 개발자라는 문득 생각 들었다.
이해 안된다고 그냥 넘어갔던 별 찍기 문제를 기어코 다시 마주했고
'이걸 이제와서 또 하네.. 진작 해볼걸' 같은 한심한 생각도 들었지만
그래도 피하지 않고 포기하지 않고 이해하려고 또 덤벼든
나 자신에게 오늘의 칭찬과 보상을 주기로 했다. ( TMI : 저녁에 낙성대입구에 고등어회 먹으러 갈 예정)
자바를 초창기에 공부하면서 옆자리에 앉은 전공자에게 어떻게 하면 잘할 수 있냐 물으니
돌아왔던 대답은 '무조건 찍어보지만 말고 일단 먼저 생각해보라는 것'이었는데
그 말이 이제는 공감되는 것 같다.
2차원 배열 별 찍기
for(int i=0;i<3;i++){ // i값이 '1'이라면 한 줄만 출력
for(int j=0;j<5;j++){
System.out.print("*"); // 안쪽 for문의 별(*) 5개 출력
}
System.out.println(""); // 한 줄 출력이 끝나면 줄 바꿔주는 역할 println("")
}
별 찍기 문제는 호락호락 하지 않기 때문에
이름대로(?) 별의별 모양을 찍어달라는 문제가 많다.
왼쪽 정렬된 별 찍기
for(int i=1; i<6; i++){ // i값을 '0'으로 할 경우 처음에 아무것도 없는 '1'라인 출력
for(int j=0; j<i; j++){ // i값은 '1'일 때 j값은 0부터 시작하며 점점 증가
System.out.print("*");
}
System.out.println("");
}
for (int i = 1; i < 6; i++)
바깥쪽 for문은 1부터 5까지의 값을 갖는 i를 반복하며, 각각의 값에 따라 한 줄을 출력한다.
for (int i = 1; i <= 5; i++) { // 1부터 5까지 반복하는 바깥쪽 루프
for (int j = 0; j < i; j++) { // i의 값에 따라 별(*)을 출력하는 안쪽 루프
if (j < i) { // 현재 위치의 j가 현재 i보다 작으면 참
System.out.print("*"); // 별(*)을 출력
} else if (i < j) { // 현재 위치의 i가 현재 j보다 작으면 참 (항상 거짓)
System.out.print(""); // 아무것도 출력하지 않음
}
}
System.out.println(); // 한 줄이 끝날 때마다 줄바꿈
}
위의 코드는 동일한 결과를 출력하지만 조건문 if, else if를 사용했다는 점에서 차이가 있는데
굳이 출력되지 않는 공백을 else if ( i < j )를 통해 " "을 찍어줬다.
chat GPT를 통해 얻은 답변이니 가벼운 마음으로 참고하시길
첫번째 자리에 별이 고정으로 박혀있는 5층 짜리 별탑을 찍어줬다면
마지막 자리에 별이 고정으로 박혀있는 5층 짜리 별탑은 어떻게 찍을까?
오른쪽 정렬된 별 찍기
for (int i = 1; i <= 5; i++) { // 1부터 5까지의 값을 가지는 바깥쪽 루프
for (int j = 5; j > 0; j--) { // 5부터 시작하여 1까지 감소하는 안쪽 루프
if (i < j) { // 현재 i 값이 j 값보다 작으면 참
System.out.print(" "); // 공백 출력
} else {
System.out.print("*"); // 별(*) 출력
}
}
System.out.println(""); // 한 줄이 끝날 때마다 줄바꿈
}
참고로 System.out.print(" ")에서
"" (빈 문자열)과 " " (공백) 두 가지의 차이점을 잘 구분하도록 한다.
그렇지 않으면 왼쪽과 같은 모양이 나올 수도 있다.
피라미드 모양 별 찍기
중첩된 for문을 사용해 좌우 정렬된 삼각형 모양을 찍먹 해봤다면
피라미드 모양으로 별 찍는 방법은 아래와 같다.
for (int i = 0; i < 4; i++) { // 바깥쪽 루프: i는 0부터 3까지 반복
for (int j = 0; j < 3 - i; j++) { // 안쪽 루프 1: j는 0부터 (3 - i)까지 반복
System.out.print(" "); // 공백 출력
}
for (int j = 0; j < 2 * i + 1; j++) { // 안쪽 루프 2: j는 0부터 (2 * i + 1)까지 반복
System.out.print("*"); // 별(*) 출력
}
System.out.println(""); // 한 줄 출력이 끝나면 줄바꿈
}
아래 표에서 3, 2, 1 숫자로 채워진 칸을 보면 밑으로 갈 수록 빈칸이 줄어드는 것을 볼 수 있다.
3 | 3 | 3 | ★ | |||
2 | 2 | ★ | ★ | ★ | ||
1 | ★ | ★ | ★ | ★ | ★ | |
★ | ★ | ★ | ★ | ★ | ★ | ★ |
i = 0 일 때 첫번째 안쪽의 for문 for(int j=0;j<3-i;j++) 조건에 맞게 3 - i; 결과가 3이 나오는데
이는 공백이 3번 출력된다는 것을 알 수 있다.
그렇기 때문에 i = 1 일 경우는 3 - i; 의 결과는 2가 될 것이고 공백이 2번 출력되며
i = 3 일 경우에는 3 - 3 = 0
즉, 공백 없이 없기 때문에 두번째 안쪽 for문의 for (int j = 0; j < 2*i + 1; j++)
조건에 맞는 별(*)이 7번 출력되는 것을 볼 수 있다.
주어진 코드의 실행 과정을 나타낸 것이다.
(각 줄은 바깥쪽 for문의 반복 횟수 i를 나타냄)
- i가 0일 때:
- 첫 번째 안쪽 for문(for (int j = 0; j < 3 - i; j++))에 의해 3 - 0 = 3번 공백 출력
- 두 번째 안쪽 for문(for (int j = 0; j < 2 * i + 1; j++))에 의해 2 * 0 + 1 = 1번 별(*) 출력
- i가 1일 때:
- 첫 번째 안쪽 for문(for (int j = 0; j < 3 - i; j++))에 의해 3 - 1 = 2번 공백 출력
- 두 번째 안쪽 for문(for (int j = 0; j < 2 * i + 1; j++))에 의해 2 * 1 + 1 = 3번 별(*) 출력
- i가 2일 때:
- 첫 번째 안쪽 for문(for (int j = 0; j < 3 - i; j++))에 의해 3 - 2 = 1번 공백 출력
- 두 번째 안쪽 for문(for (int j = 0; j < 2 * i + 1; j++))에 의해 2 * 2 + 1 = 5번 별(*) 출력
- i가 3일 때:
- 첫 번째 안쪽 for문(for (int j = 0; j < 3 - i; j++))에 의해 3 - 3 = 0번 공백 출력
- 두 번째 안쪽 for문(for (int j = 0; j < 2 * i + 1; j++))에 의해 2 * 3 + 1 = 7번 별(*) 출력
'활동 > 호기심' 카테고리의 다른 글
아니 자바에서 static이 도대체 뭔데 (클래스와 메소드) (0) | 2023.08.29 |
---|---|
클래스(class), 객체(object), 인스턴스(instance) 차이점 비교 (0) | 2023.08.28 |
While문과 for문의 차이점 (+코드를 간결하게 만들어주는 람다 표현식 설명도 한 스푼) (0) | 2023.08.24 |
String.valueOf()와 Integer.toString() 차이점은 Null 값 처리 (0) | 2023.08.23 |
해시함수 정리 (Hash 충돌 발생 원인과 해결방법 / Hash Table과 Hash Map 차이점) (0) | 2023.08.22 |