코드 그라데이션

230327 별찍기 피라미드 / 다이아몬드 모양 추가 정리 본문

Java, SpringBoot 추가 공부

230327 별찍기 피라미드 / 다이아몬드 모양 추가 정리

완벽한 장면 2023. 4. 1. 20:22

정리하자면, 피라미드와 다이아몬드는 일종의 idea가 꽤 필요한 작업이다.

피라미드

public class MakeStar04Sample {

  public static void main(String[] args) {
    /*
    일단 피라미드를 그리려면 모양을 쪼개서 살펴보자
    왼쪽 직각삼각형과 오른쪽 직각삼각형
    혹은 가운데를 기준으로 왼쪽과 오른쪽에 하나씩 더 찍어주면, 완성이 된다 뭐 요런 느낌으로다가.
     */

    //4.피라미드
    for (int i = 0; i < 5; i++) {  // 0 1 2 3 4
      for (int j = 4; j >= 0; j--) { // 4 3 2 1 0
        if (i < j) { //4 3 2 1 / 4 3 2 /4 3 / 4
          System.out.print(" ");
        } else { //0 / 1 0 / 2 1 0 / 3 2 1 0 / 4 3 2 1 0
          // 1 +2  3 5 7 9
          // 한 줄에 있는 모든 별을 찍는 for 문
          for (int k = 0; k <= i * 2; k++) {
            System.out.print("*");
          }
          break;
        }
      }
      System.out.println();
    }
    /*
    먼저 피라미드 1 설명
    for (int i = 0; i < 5; i++) {
    여기서 i=0 인 것은 크게 상관이 없어 보인다.
    바깥쪽 for문은 줄을 의미하는 것이고(행)
    안쪽 for문이 안에서 무엇을 찍을 것인가를 의미
    일단, 공백부터 봤을 때 첫줄 4 / 둘째 3 / 셋째 2 / 넷째 1 / 마지막 없음 => 공백이 계속 감소 중.
    i는 계속 바뀌지만, j는 항상 다섯이잖아.
    그럼 i에 대한 식으로 j도 나타낼 수 있나? 를 고민한다.
    공백은 자연스럽게 하나씩 줄어들게 하고 싶어요.
    i는 증가하니까, 그럼 i에 대한 식으로 공백을 나타낼 수 있을까를 고민.

     */
    // i: 0, 공백: 4, j:4~0 4 3 2 1
    // i: 1, 공백: 3, j:4~0 4 3 2
    // i: 2, 공백: 2, j:4~0 4 3
    // i: 3, 공백: 2, j:4~0 4
    // i: 4, 공백: 0 j: 4~0 / x
    // 즉, 규칙성 : i가 1증가 -> y는 1 씩 감소중.
    // 어 뭐야, 하나씩 보면, i가 0일때는 0보다 크고, i가 1일때는 1보다 크고
    // i가 2일 때는 2보다 크고, i가 3일 때는 3보다 크고, i가 4일 때는 4보다 커야ㅎ하므로,,, 없네!


    /*
    이제 별의 개수를 보자
    역시 j는 변하지 않으니까 변하고 있는 i에 대해서 식을 만들어보자.
    근데 보다보니까, j와 i의 연관 식으로 굳치 만들 필요가 없어.
    그냥 증가식 그 자체로 규칙성이 보이고 있잖아.
     */
    // i: 0, 별: 1, j:4~0
    // i: 1, 별: 3, j:4~0
    // i: 2, 별: 5, j:4~0
    // i: 3, 별: 7,
    // i: 4, 별: 9
    // 별의수 = i * 2 + 1

    // 0~5 -> 6
    // 1~5 -> 5

    // 0~i*2 -> i*2+1
    // break는 살짝 어색



    // 피라미드 2 수정
    /*
    break를 탈피하기 위해서...
    별을 찍는 건 공백이랑 상관없이 별만 잘 찍으면 되는 것 아니야? 에 대한 응답.
    앞선 코드에서 만약 break를 안 해줬다고 보면,
    일단 이 break는 두 번째 for문에 (j에) 걸린 break.
    그럼 공백을 i<j에만 찍고 아닐 때는 i>j인 경우에는 else에 걸려야 하는데, 그런 상황에서는 else에 있는 것이 몇 개가 될 줄 모른다.
              // 한 줄에 있는 모든 별을 찍는 for 문
          for (int k = 0; k <= i * 2; k++) {
            System.out.print("*");
          }
          지금 얘는 딱 한 번만 실행되어야 별이 5개가 나온다.
          그런데 break가 없으면 계속 걸리므로 5개씩 여러번이 찍힐 수 있다는 말.
          (잘은 모르겠지만, 일단 그렇게 받아들이자)


     */
    for (int i = 0; i < 5; i++) {  // 0 1 2 3 4
      for (int j = 4; j >= 0; j--) { // 4 3 2 1 0
        if (i < j) { //4 3 2 1 / 4 3 2 /4 3 / 4
          System.out.print(" ");
        }
      }
      for (int k = 0; k <= i * 2; k++) { // 좀 헷갈리니까. k<i*2+1 개라고 해도 무방함.(개수만 맞으면 되거든)
        System.out.print("*");
      }

      System.out.println();
    }
/*일단 피라미드 1과 피라미드 2의 차이는
for (int k = 0; k <= i * 2; k++) {
            System.out.print("*");
          }
  얘가 굳이 else 안에 들어있을 필요가 없다.
  그래서 뺐던 것.

  생각해보면 피라미드2 에서도 공백은 i가 j보다 작을 때만 찍으면 되는 것이고,
  그렇지 않은 경우에는 아무 일도 안 하면 되는데,
  굳이굳이굳이 피라미드2에서는 5번을 돌고 있다는 것.

  그래서 불필요함을 삭제하기 위해서
  피라미드 3에서는 for문 안에 있는 if를 전체 조건식으로 바꿔버리는 것이라고 생각하면 된다.
  매우 깔끔해졌음.
 */

    // 피라미드 3
    for (int i = 0; i < 5; i++) {  // 0 1 2 3 4
      for (int j = 4; j > i; j--) { // 4 3 2 1 // 4 3 2 // 4 3 // 4
        System.out.print(" ");
      }
      for (int j = 0; j <= i * 2; j++) { // 0 // 0 1 2 // 0 1 2 3 4 // 0 1 2 3 4 5 6 // 0 1 2 3 4 5 6 7 8
        System.out.print("*");
      }
      System.out.println();
    }
  }

}

 

 

다이아몬드

1.

public class MakeStar05Sample {

  public static void main(String[] args) {

    //위: 피라미드 모양
    // 아래 : 역피라미드 모양
    /*
    사실 피라미드 두 개를 찍는다고 보면 된다.
    사실 두 개를 더한 것이 다이아몬드의 크기이다.
    그런데 자바에서는 정수/정수는 그냥 정수
    따라서 int size=5 라고 했을 때,
    size/2 == 5 가 되는 것.
    그래서 size / 2 + 1 해준 이유는 3을 만들고 싶어서, 나머지 하나를 위에 것이 가져가게 만들어 준 것.
     */
    for (int i = 0; i < 3; i++) {  // 0 1 2 3 4
      for (int j = 2; j > i; j--) { // 4 3 2 1 // 4 3 2 // 4 3 // 4
        System.out.print(" ");
      }
      for (int j = 0; j <= i * 2; j++) { // 0 // 0 1 2 // 0 1 2 3 4 // 0 1 2 3 4 5 6 // 0 1 2 3 4 5 6 7 8
        System.out.print("*");
      }
      System.out.println();
    }
    
    // 역피라미드
    // i:0, 공백: 1, 별: 3
    // i:1, 공백: 2, 별: 1
    /*
    이것도 마찬가지로
    공백을 찍고, 별을 찍을 때는 공백과 무관하게 찍어주면 된다.
    
    별의 개수는 한 줄 내려갈 때마다 두 개씩 줄어든다.
    
    그런데 여기서 고민할 것.
    i가 1 증가하면 별의 개수는 i*2(=> 2) 만큼 증가해요.
    예를 들면, j>i*2에서
    처음에 i=0 일 때는 0이잖아.
    i = 1로 바꾸면 
    별의 개수는 0+2 하면 되는 것.
    */

    for (int i = 0; i<2; i++) {
      for (int j = 0; j<=i; j++) {
        System.out.print(" ");
      }
      for (int j = 3; j>i*2; j--) { // 줄어드는 것도 두 배씩 줄어드므로.
        System.out.print("*");
      }
      System.out.println();
    }
  }
}

 

다이아몬드 윗 부분은 피라미드처럼 짜면 되는 것이고,

이제 문제는 역피라미드 부분을 어떻게 짤 것이냐가 남음.

 

다이아몬드 문제에서는 가운데 처리 때문에 고민을 더 해봐야 한다.

 

달리 생각해보면, 가운데 줄을 제외하면 위 아래 대칭이므로,

위 도형 + 가운데 한 줄 + 아래 도형

이 형태로 코드를 짤 수도 있다.

 

그런데 선생님이 구현하신 부분은 그냥 불균형적으로 위 피라미드 + 역피라미드 형태로 짜셨다.

 

위 for문에서

 for (int i = 0; i < 3; i++) {

for (int i = 0; i<2; i++) {

 

3의 의미와 2의 의미를 따로 찾는 것이 나을 것 같아요.

 

따지고 보면 이게 줄의 개수.

다이아몬드의 사이즈는 3+2 해서 5

 

누가 하나를 더 가져가야 하는 상황이 필연적으로 발생(이 상태에서는)=> 홀수 다이아몬드이기 때문에.

 

프로그래밍에서는 필연적으로,

정수/정수 = 정수이다. 따라서  의도한대로 하려면 +1

 

 public class DiamondStar {   
    public static void main(String[] args) {
    
    Scanner sc = new Scanner(System.in);
    System.out.print("숫자 입력 : ");
    int size = sc.nextInt();

    for (int i = 0; i < size / 2 + 1; i++) {  // 0 1 2 3 4 프로그래밍에서는 필연적으로, 정수/정수 = 정수이다. 따라서  의도한대로(남은 한 줄을 위 피라미드가 가져가게) 하려면 +1
      for (int j = size / 2; j > i; j--) { // 4 3 2 1 // 4 3 2 // 4 3 // 4 // 이게 원래 2로 구현이 되어있었는데, 이게 따지고 보면 숫자 2가 아니라 size / 2의 결과값이 아니었을지 추측해봄. 마지막줄은 공백이 없으니 제외해야 하므로??
        System.out.print(" ");
      }
      for (int j = 0; j <= i * 2; j++) { // 0 // 0 1 2 // 0 1 2 3 4 // 0 1 2 3 4 5 6 // 0 1 2 3 4 5 6 7 8
        System.out.print("*");
      }
      System.out.println();
    }
    // i:0, 공백: 1, 별: 3
    // i:1, 공백: 2, 별: 1
    for (int i = 0; i < size / 2; i++) {
      for (int j = 0; j <= i; j++) {
        System.out.print(" ");
      }
      for (int j = size - 2; j > i * 2; j--) { //여기
        System.out.print("*");
      }
      System.out.println();
    }
    공백과 별 개수
    // size: 5 -> 3
    // size: 7 -> 5
    // size: 9 -> 7
    // size: 11 -> 9 아 두개씩 줄어드는 거구나, 그래서 size - 2


	}

}
많이 어렵다....

 

 

 

 

 

 

 

 

 

Alt Enter Quick Extion introduce Local variable

 

728x90
Comments