Algorithm/알고리즘 문제 풀이
C - [혼공C] 17장, 도전 실전 예제
유로 청년
2024. 6. 20. 16:22
1. 문제
학생의 수를 입력 받은 뒤, 학생 수 만큼 국어, 영어, 수학 점수를 입력해 총점, 평균, 학점을 구하고 총점 순으로 정렬해 출력합니다. 학점은 평균이 90점이상이면 A, 80점 이상이면 B, 70점 이상이면 C, 그 외는 F로 평가합니다.
2. 생각
- 학생의 점수들과 총점, 평균, 학점을 저장해야 하기 때문에 구조체를 사용한다.
- 학생의 수를 입력 받은 뒤, 이를 malloc 함수를 이용하여 학생의 수만큼 동적할당 받는다.
- Quick Sort 알고리즘을 통해 정렬한다.
- Padding byte를 고려하여 Padding byte가 최소화 되도록 구조체의 맴버들의 위치를 설정한다.
3. 풀이 및 코드 분석
#include <stdio.h>
#include <stdlib.h>
// Structure
typedef struct {
unsigned int student_id;
// Score of subject
unsigned char korean;
unsigned char english;
unsigned char math;
// Information of score.
unsigned short sum;
double mean;
char grade;
// Name
char name[30];
}STUDENT;
// Function prototype
void get_N_of_Student(unsigned char* p_NofStudent);
void get_Scores(STUDENT* p_list, unsigned char NofStudent);
void compute_grade(STUDENT* p_list, unsigned char NofStudent);
char getGrade(double mean);
void print_the_list(STUDENT* list, unsigned char NofStudent);
void quickSort(STUDENT* list, unsigned char left, unsigned char right);
void swap(STUDENT* list, unsigned char i, unsigned char j);
unsigned char partition(STUDENT* list, unsigned char left, unsigned char right);
// Main method
int main(void) {
unsigned char NofStudent = 0;
get_N_of_Student(&NofStudent);
STUDENT* list = (STUDENT*)malloc(NofStudent * (unsigned int)sizeof(STUDENT));
get_Scores(list, NofStudent);
compute_grade(list, NofStudent);
print_the_list(list, NofStudent);
quickSort(list, 0, NofStudent - 1);
print_the_list(list, NofStudent);
free(list);
return 0;
}
// Get number of student.
void get_N_of_Student(unsigned char* p_NofStudent) {
while (1) {
printf("$ 학생의 수를 입력 : ");
scanf_s("%hhu", p_NofStudent);
if (*p_NofStudent <= 0) puts("0 이하의 숫자를 입력하셨습니다.");
else return;
}
}
// Get score of students.
void get_Scores(STUDENT* p_list, unsigned char NofStudent) {
for (unsigned char i = 0; i < NofStudent; i++) {
printf("학번 : ");
scanf_s("%u", &(p_list[i].student_id));
rewind(stdin);
printf("이름 : ");
scanf_s("%s", p_list[i].name, (unsigned int)sizeof(p_list[i].name));
printf("국어, 영어, 수학 점수 : ");
scanf_s("%hhu %hhu %hhu", &(p_list[i].korean), &(p_list[i].english), &(p_list[i].math));
}
}
// Compute grade.
void compute_grade(STUDENT* p_list, unsigned char NofStudent) {
for (unsigned char i = 0; i < NofStudent; i++) {
unsigned short sum = 0;
sum += p_list[i].korean + p_list[i].math + p_list[i].english;
p_list[i].sum = sum;
p_list[i].mean = sum / 3.0;
p_list[i].grade = getGrade(sum / 3.0);
}
}
// Get grade.
char getGrade(double mean) {
switch ((int)(mean / 10)) {
case 10:
return 'A';
case 9:
return 'A';
case 8:
return 'B';
case 7:
return 'C';
default:
return 'F';
}
}
// Print the list.
void print_the_list(STUDENT* list, unsigned char NofStudent) {
puts("\n# 정렬 전 데이터...");
for (unsigned char i = 0; i < NofStudent; i++)
printf("%4u %4s %3hhu %3hhu %3hhu %3hu %6.1lf %2c\n", list[i].student_id, list[i].name, list[i].korean,
list[i].english, list[i].math, list[i].sum, list[i].mean, list[i].grade);
}
// QuickSort
void quickSort(STUDENT* list, unsigned char left, unsigned char right) {
if (left >= right) return;
unsigned char pivot = partition(list, left, right);
quickSort(list, left, pivot - 1);
quickSort(list, pivot + 1, right);
}
// Partition
unsigned char partition(STUDENT* list, unsigned char left, unsigned char right) {
unsigned char pivot = (unsigned char)(rand() % (right + 1 - left) + left);
swap(list, pivot, right);
unsigned char i = left - 1, j = left;
while (j < right) {
if (list[j].sum > list[right].sum) swap(list, ++i, j);
j++;
}
swap(list, ++i, right);
return i;
}
// Swaping
void swap(STUDENT* list, unsigned char i, unsigned char j) {
STUDENT temp = list[i];
list[i] = list[j];
list[j] = temp;
}