자료구조(4)_ homework 문제풀이(1)

지난 주 문제에 대한 선생님 풀이

//알파벳 개수를 입력 받아
//임의 대문자알파벳들을 저장

//한줄에 5개씩 출력

//A : 00개 B: 00개 C: 00개 G:00개 H: 00개

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
    
    int su;
    printf("개수 입력 : ");
    scanf_s("%d", &su);

    char * pt = (char *)malloc(su);

    srand((unsigned)time(NULL));

    for (int i = 0; i < su; i++) {
        pt[i] = rand() % 26 + 65;
    }

    int su1;
    printf("한 줄에 출력될 개수 입력 :");
    scanf_s("%d", &su1);

    printf("\\\\ 대문자 출력 \\\\\\ \n");
    for (int i = 0; i < su; i++) {
        printf("%-3c", pt[i]);         
        if (i % su1 == su1 - 1 || su - 1 == i) { 
            printf("\n");
        }
    }
    // -2를 붙인 이유 : -를 쓰면 좌측 정렬을 써라. 그냥 3은 우측 정렬
	// if문의 왼쪽 -> 갯수에 맞게 출력 || 오른쪽 -> 마지막 출력

    printf("\n각 대문자 개수 출력 \n");
    int tfk = 0; // 
    for (char ch = 'A'; ch <= 'Z'; ch++) {
        int  cnt = 0;
        for(int i = 0; i <su; i++){
            if (pt[i] == ch) {
                cnt++;
            }
        }
        if (cnt != 0) {
            printf("%3c : %d개 " , ch, cnt); 
            tfk++;
            if (tfk % 5 == 0 || ch == 'Z') { 
                printf("\n");
            }
        }
        else if (ch == 'Z' && tfk %5 != 0) { 
            printf("\n");
        }
    }

        // cnt 0개 일 때. 즉   Z가 없을 때 // else if 로 묶어놓은 이유 -> if가 맞으면 if만 보고 끝내버리면 되는데 아래가 if면 아래도 봐야해
    //printf("???????????");
    free(pt);

    return 0;
}

조금 설명을 해보자. 지난 번 내가 짰던 코드는 cnt라는 알파벳들을 차례대로 담는 배열을 만들었다. 하지만 그렇게 짤 필요가 없다.

위 코드상 주의해야할 부분은 (1) 대문자 출력 부분이다. 주의해야 할 건. 알파벳 개수 전체에 대한 포문을 돌면서 if문을 걸어주는데 if문의 조건은 아래와 같다 if(i % su1 == su1-1 || su - 1 = i) su1은 한 줄에 출력될 개수를 말한다.

i % su1 == su1 -1 은 i를 su1으로 나눴을 때, 나머지가 su1-1과 같으면, (i가 0번부터 시작하니까.) 개행한다. 예를 들어 su1이 5라고 한다면 0,1,2,3때는 넘어가지만 5번째는 개행읋 하게되는 거다.

그런데   (or) su -1 == i를 해줬다. 이건 마지막 출력을 한 뒤 개행을 해주는 것을 말한다. 맨 마지막 포문이 끝난 뒤 printf(“??”); 이런 식의 코드를 집어 넣게 된다면 문자의 바로 뒤에 바로 붙게되는 데 이걸 처리해준 것이다.

(2) 두 번째로 살펴볼 부분은 각 대문자의 개수를 5개씩 출력하는 코드다.

int tfk는 왜 선언했을까? printf를 몇 번했는지, 즉 5개를 출력했는지를 확인하기 위해 쓰인다.

첫 번째 포문은 A부터 Z까지 돈다. 그 와중에 cnt는? cnt변수는 A~Z까지 포문을 돌면서 아래에 포문을 하나 더 생성해주어, 각 해당하는 알파벳이 몇번이나 출력되었는지를 찾아서 더해주는 변수다. 정리하자면 이중포문을 왜 사용했냐면 첫번째 포문에서 A~Z까지 돌고, 그 안에 또 포문을 넣어서 랜덤으로 생성된 값들이 얼마나 찍히게 되었는지를 cnt에 저장한다.

이 때 (cnt != 0)은 왜 들어가는 걸까? cnt가 0이면 출력할 필요가 없기 때문이다. 따라서 cnt != 0 을 넣어 하나라도 생성된 알파벳은 추력을 해준다.

if(tfk % 5 == 0 || ch == 'Z') 따라서 5개씩 출력하기로 하였으니, 개행을 해주는 조건으로써 tfk를 5로 나눠서 나머지가 0일 때와 ch ==’Z’, 즉 마지막이 Z로 끝났을 때 개행을 해주기 위해서 위 조건을 추가해준다.( 이 방식은 위에서 했던 방식과 동일)

그런데 여기서 아래에 추가적으로

else if를 걸어줘야 한다

q) 왜 if는 안될까? 만약에 if걸어준다면 아래로 내려가면서 해당하는 것들을 다 하나씩 살펴보기 때문이다. 즉 속도를 높이기 위해서는 else if로 처리해주는 것이 좋다. 또한 else if로 처리를 해줘야 cnt == 0일 때로 접근되기 때문이다.

(ch == 'Z' && tfk % 5 != 0) 는 cnt가 0일 때, 즉 Z가 안나오고 끝이 났을 때를 대비한 것이다. Z가 안나왔을 때, 끝이날 경우 개행이 안될 수 있기 때문이다.

tfk가 5가 아니란 건 왜 넣어줘야 할까? tfk % 5 ! = 0일 때를 넣어주지 않으면, tfk %5 가 0일 때, 개행을 해주는데 아래에서 개행을 한번 더 해주기 때문이다. 즉 Z로 끝나지 않으면서 5개가 딱 맞춰서 출력될 때는 개행을 한번 더해주게 된다. 이를 없애기 위해 else if안에다가 tfk % 5 != 0을 넣어주는 것이다.


추가 과제 : 스위치케이스로 메뉴를 만들어서 메뉴를 누를 때마다 설정이 되도록 만들어주기.


참고자료

kg아이티뱅크학원 (자료구조 수업)

0%