거북이처럼 천천히

C - [혼공C] 17장, 도전 실전 예제 본문

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;
}

 

출력 결과