블가다의 C언어 강좌) 육망성 만들기!

2017. 5. 15. 22:50프로그래밍(이전)/C

우선 2중 반복문은 상당히 지옥이란걸 알고 들어가자.
순서도 없이 말로만 설명하는것은 상당히 이해력이 좋아야 가능하므로
이 글을 보고 이해가 되지 않는다 해서 작성자나 독자나 이상한 사람 하나 없다.



int a,b,c;

scanf("%d",&a);



우선 처음은 아주 아주 간단하게 육망성의 크기와, 반복문에 쓰일 정수형을 선언했다. 

반복문에서 똑같이 i만 써대다가 겹처서 터지기 마련이기 때문이다.


정수에 대해 설명해보자면
a=> 입력받는값(4*a가 육망성의 세로길이)
b=> 지금 입력중인 줄의 순서
c=> 2중포문안의 요소(신경쓸필요 없다.)



for(b=1;b<=4*a;b++){


}



길이는 스캔한 값의 4배이다. 그것은 아래 예제에서 수 세어보면서 확인하도록 하자.
1차 포문의 완성이다.... 시작이군....

이 글에서 예시를 세어보라는 말을 많이 하게 될텐데,
그 이유는 내가 육망성의 창시자가 아니라 모양 자체를 해명하려 들기에 어렵기 때문이다.
왜 몇번째 줄에 몇개의 별이 있어야 하는지 조차 모른다.

육망성은 총 5곳으로 나누어서 만들 것이다.
예시) 5 입력시 나오는 육망성을 쪼개 보겠다



*

***
*****
*******
*********
***************************
*************************
***********************
*********************
*******************
*********************
***********************
*************************
***************************
*********
*******
*****
***
*



*
***
*****
*******
*********

----------------------------------------------------------------------------------------

***************************
*************************
***********************
*********************

----------------------------------------------------------------------------------------
*******************

----------------------------------------------------------------------------------------

*********************
***********************
*************************
***************************

-------------------------------------------------------------------------------------------

*********
*******
*****
***
*



간단히 네 부분으로만 잘라도 되는데 왜 이렇게 하나를 더 자르는지 물어보는 사람이 있을까봐 답한다. 2번째 부분이나 3번째 부분에서 저 부분을 포함시켜 4 파트로 만들면 '균형감'이 없다. 이걸 잘 포장해서 말하면 '유지보수를 위함'이 되고, 나쁘게 말하자면 '균형맞추는 결벽증'이다.


솔직히 취향차이라고 생각한다. 하지만 무조건 메모리를 최소로 해야 하거나 줄 수를 줄여야 한다면 포함시키는것이 나은것 사실이다.

우선 첫번째 파트부터 가보자.


*
***
*****
*******
*********



if(1<=b&&b<=a){

for(c=1;c<=3*a-b-1;c++){

printf(" ");

}

for(c=1;c<=2*b-1;c++){

printf("*");

}

printf("\n");

}  



간단한 피라미드이다. 조건문으로 1파트를 분기했다.

하지만, 가운데 정렬로 편하게 보이는 블로그 화면과 다르게, C언어 안에서 직접 띄어쓰기로 중간정렬이 된 것 처럼 해주어야 한다.
위 육망성 예제에서 숫자를 세어보면, 위 파트에서 가장 마지막 줄은  2*a-1만큼 띄어쓰기가 되어 있다. 줄이 위로 올라갈수록 띄어쓰기는 1개씩 더해진다. 이제 남은일은 연산자 짬뽕.

(2*a-1)+(a-b)만큼 띄어쓰기해주면 된다는걸 알 수 있다. 계산이 힘들어도 최대한 직접 구하려고 하고 넘어가는 편이 좋다.

두번째 파트


***************************
*************************
***********************
*********************



else if(a<b&&b<2*a){

for(c=1;c<=b-a-1;c++){

printf(" ");

}

for(c=1;c<=8*a-2*b-1;c++){

printf("*");

}

printf("\n");

}



a+1 ~ 2*a-1 줄 사이`다.(사이다???)

띄어쓰기는 단순하게 현재 줄 순서에다가 2분기의 첫번째줄 순서를 뺀 b-(a+1) 해서 b-a-1이 나왔다.

별을 써넣는 2차 포문은 3분기와 같이 설명한다.

세번째 파트


*******************



else if(b==2*a){

for(c=1;c<=a-1;c++){

printf(" ");

}

for(c=1;c<=4*a-1;c++){

printf("*");

}

printf("\n");

}



이 줄은 2*a번째 줄이다.
띄어쓰기는 예제에서 세어보면 알겟지만 a-1번 하면 된다.
위의 2분기에서 계산하는 방식으로 한번 더 해 봐도 a-1나온다.

들어가는 별의 개수는 4* a-1이다. 이것도 세어보면 안다.

다시 2분기로 돌아가보자.
2분기의 별의 갯수는 4*a-1에다가 순서에 맞는 짝수만큼만 더 집어넣으면 된다.
그 식이 4*a-1+2*(2*a-b)이고,
풀어서 쓰면 8*a-2b-1이다.


*********************
***********************
*************************
***************************

*********
*******
*****
***
*



else if(2*a<b&&b<3*a){

for(c=1;c<=3*a-b-1;c++){

printf(" ");

}

for(c=1;c<=2*b-1;c++){

printf("*");

}

printf("\n");

}else if(3*a<=b&&b<4*a){

for(c=1;c<=(-1)*a+b-1;c++){

printf(" ");

}

for(c=1;c<=8*a-2*b-1;c++){

printf("*");

}

printf("\n");

}



남은 4~5분기는 1~2분기에서 한 방법을 거꾸로 하면 된다.
위 1~3분기를 직접 스스로 풀 수 있을 정도로 학습이 되었다면. 이후는 쉽다. 항상 처음이 어려울뿐 같은 것을 만드는것은 일도 아니다.

이렇게 만든 코드를 합쳐보겠다.



#include <stdio.h>

#include <string.h>


int main(void)

{

int a,b,c;

scanf("%d",&a);

for(b=1;b<=4*a;b++){

if(1<=b&&b<=a){

for(c=1;c<=3*a-b-1;c++){

printf(" ");

}

for(c=1;c<=2*b-1;c++){

printf("*");

}

printf("\n");

}else if(a<b&&b<2*a){

for(c=1;c<=b-a-1;c++){

printf(" ");

}

for(c=1;c<=8*a-2*b-1;c++){

printf("*");

}

printf("\n");

}else if(b==2*a){

for(c=1;c<=a-1;c++){

printf(" ");

}

for(c=1;c<=4*a-1;c++){

printf("*");

}

printf("\n");

}else if(2*a<b&&b<3*a){

for(c=1;c<=3*a-b-1;c++){

printf(" ");

}

for(c=1;c<=2*b-1;c++){

printf("*");

}

printf("\n");

}else if(3*a<=b&&b<4*a){

for(c=1;c<=(-1)*a+b-1;c++){

printf(" ");

}

for(c=1;c<=8*a-2*b-1;c++){

printf("*");

}

printf("\n");

}

}

}



직접 IDE에서 실행시켜 보는 것을 권장한다. 물론 아래에 첨부파일을 안올린다는 것은 아니지만 자신이 복붙을 하든 배껴 쓰든 이 글을 참고해서 자신만에 것을 만들든 실행파일 실행과 컴파일 후 디버그는 느낌상 차이가 좀 있다.


이중포문은 경험만 많이 쌓는다고 실력이 늘지 않는다.
기본적인 계산과 반복되는 for문에 대한 완벽한 이해. 이 두가지가 철저해야한다.
경험은 그 나중 이야기이다.