지난 주 문제에 대한 선생님 풀이
//알파벳 개수를 입력 받아
//임의 대문자알파벳들을 저장
//한줄에 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아이티뱅크학원 (자료구조 수업)