{{{리 포 트{{{{{{{제목 : Sorting Program{{{과목 : 데이터구조2교수 : 강 수 용학과 : 컴퓨터교육과학번 : 2002031455성명 : 윤 경 훈{1. Diagram{2. 함수 설명▶ 파일을 읽어들이는 것과 관련되는 함수들1) char *trim(char *s): 공백을 제거하는 메인 함수이며, right_trim(), left_trim(), center_trim()함수를 차례로 실행시키며, 공백이 제거된 문자열을 리턴 한다.2) void right_trim(char *s){: 오른쪽 공백을 제거하는 함수이다.- i의 초기값을 strlen(s)-1로 해준 이유 : 배열은 0부터 시작하므로 실제 문자열의 끝 은 s[strlen(s)-1] 부터이기 때문이다.- 문자열의 마지막에서부터 시작해서 공백이나 라인개행문자가 나올때까지 그 부분을 널문자(0x00)으로 바꿔줘서 공백과 라인개행문자를 없애준다.3) char *left_trim(char *s){: 왼쪽 공백을 제거하는 함수이다.- i값을 0으로 초기화하여 문자열의 초기에서부터 공백이 나올때까지 i값을 누적시켜준 다.- return 값이 s+i인 이유 : 앞의 공백을 제거 하기 위해 문자열 포인터를 빈 공백의 숫 자만큼 뒤로 이동시켜주는 것이다.{s[0]s[1]s[2]s[3]s[4]s[5]s[6]s[7]s[8]s[9]ABCEEF...초기 문자열 sfor문 실행 후 i값은 3이 된다.(s[3]부터 공백 문자가 아니기 때문에..);s+i 란 수식은 s[0]의 주소에 i만큼 뒤로 이동한다는 것이다.즉, s[0]+3이 되기에 s[3]을 가리키게 된다.만약 buf=left_trim(s); 가 실행 됐다면..{s[0]s[1]s[2]s[3]s[4]s[5]s[6]s[7]s[8]s[9]buf[0]buf[1]buf[2]buf[3]buf[4]buf[5]buf[6]ABCEEF...4) char *center_trim(char *s);: 가운데 공백을 제거하는 함수이다.{- 이미 center_trim()함수가 실행되기 전에 right_trim(), left_trim()함수가 실행되어서 좌우 공백과 불필요한 문자가 제거된 상태이다. 즉 양쪽 끝에 군더더기 데이터가 없다 는 말이다. center_trim()은 이같은 전제조건으로 설계되었다.- 새로운 버퍼 문자열을 하나 만들어서 추출된 데이터를 저장한다. 데이터들 사이에는 구분하기 위해 공백문자를 하나 넣어주고, 마지막에는 널문자(0x00)를 넣어줘서 문자열 을 종료시킨다.- 이 함수의 키포인트는 b_duing이라는 변수이다. b_duing이라는 변수는 문자열을 저장 하기 위한 용도로 사용되는데, b_duing=0일때는 데이터를 처리하고 있다는 뜻이고, b_duing=1일때는 데이터를 처리하지 않는다는 뜻이다. b_duing=0 으로 초기화 되는 이 유는 위에서 말했듯이 맨앞쪽에 군더더기 데이터가 없다는 전제가 있기 때문이다. 즉, s[0]부터 쓸모있는 데이터가 들어가 있기에 b_duing=0으로 초기화 한것이다. 공백문자 가 아니고 b_duing=0이라면 진행중이란 뜻이므로 buf에 문자 하나를 저장하고 buf_pos 의 값을 하나 올려줘서 다음에 저장할 문자위치를 지정한다. 공백문자가 아니고 b_duing=0도 아니란 말은 새로운 데이터를 발견했다는 뜻이므로, b_duing=0으로 바꿔 진행중으로 표시하고, buf에 데이터를 저장한다.마지막으로 공백문자인데, b_duing값이 0(진행중)인 경우는 데이터의 끝을 의미하므로, 해당 데이터의 마무리 작업(buf에 추출된 데이터를 서로 구분하기 위한 구분자로 공백 을 넣어주고, b_duing값을 진행중이 아니라고 바꿔준다.)을 해준다.초기값{[0][1][2][3][4][5][6][7]...sS-IDDS...bufi=0, b_duing=0{[0][1][2][3][4][5][6][7]...sS-IDDS...bufSi=3, b_duing=0{[0][1][2][3][4][5][6][7]...sS-IDDS..bufS-IDi=4, b_duing=1{[0][1][2][3][4][5][6][7]...sS-IDDS...bufS-IDi=6, b_duing=0{[0][1][2][3][4][5][6][7]...sS-IDDS...bufS-IDDi=8, b_duing=1{[0][1][2][3][4][5][6][7]...sS-IDDS...bufS-IDDS▶ 파싱(parsing) 관련 함수들1) int parse_header(char *s): 헤더 데이터를 파싱하는 함수이다.{- 문자열중에서 공백문자의 갯수는 곧 과목의 갯수와 같다.{s[0]s[1]s[2]s[3]s[4]s[5]s[6]s[7]s[8]s[9]s[10]s[11]s[12]S-IDDSALPL공백 문자의 갯수는 3개, 과목도 3개이다.(DS, AL, PL)- strtok()함수를 통해서 공백을 구분자로 데이터를 나눈다. 제대로 된 데이터라면 첫번 째는 분명 S-ID일 것이다. 이것을 class_h.field의 첫번째 요소에 저장한다.- 계속 strtok()함수를 통해서 데이터를 나눈다. 제대로 된 데이터라면 그뒤의 값들은 과목명이 되므로, class_h.field[1]~field[n]까지는 과목명으로 채워진다.- class_h.field[n+1]에는 총점을 뜻하는 TOTAL"이 들어가게 된다.2) void parse_data(int pos,char *s){: 메인 데이터를 파싱하는 함수이다.- 제대로 된 데이터라면 첫번째 구간의 값은 학번이 될것이다. 이것은 문자열이므로 atoi()함수를 이용해서 정수형으로 변환하여 class_s[].field[0]에 저장한다. field[0]에는 학번을 저장하기로 미리 설계 하였기 때문이다.- sub_pos값을 1로 초기화한 것에도 알수 있듯이 과목 데이터는 field[1]부터 들어가게 된다. 과목 갯수가 n개라면.. 과목 데이터는 field[1] ~ field[n] 까지가 된다.- field[n+1] 은 각 과목의 합계인 총점을 의미한다. 루프를 돌면서 과목의 값들을 차근 차근 총점에 더해나간다.※class_h.field 와 class_s.field 의 구조{field[0][1][2]…‥[n][n+1]class_hS-ID과목명1과목명2…‥과목명nTOTALclass_s학번과목1 점수과목2 점수…‥과목n 점수총점즉, [0]번 인덱스는 학번으로 고정되며, 총점은 과목의 숫자에 따라 인덱스가 변경된다.▶ 소트(sorting) 관련 함수들책에서 볼수 있는 sort 함수를 거의 그대로 사용했습니다. 다만 모든 함수에 뒤에 key_pos가 인자가 추가되었는데, 이 key_pos는 정렬 대상을 가리켜 주는 값이 됩니다.즉 key_pos가 0 : S-ID, 1~N : 특정과목, N+1 : 총점(N = 과목숫자)이렇게 대상을 가리켜서 그 대상 값으로 비교해서 sorting을 하게 됩니다.1) void insertion_sort(SCORE list[],int n,int key_pos): 삽입 정렬 함수2) void quicksort(SCORE list[], int left, int right,int key_pos);: 퀵정렬 함수3) void adjust(SCORE list[], int root, int n,int key_pos);: 힙정렬 보조함수4) void heapsort(SCORE list[], int n,int key_pos);: 힙정렬 함수5) void merge(SCORE list[], SCORE sorted[], int i, int m, int n,int key_pos);: 병합정렬 보조함수6) void merge_sort(SCORE list[], int n,int key_pos);: 병합정렬 함수7) void merge_pass(SCORE list[], SCORE sorted[], int n, int length,int key_pos);:병합정렬 보조함수▶ 그 외 함수들1) void malloc_subject(int count): 메모리를 할당 하는 함수.{- 먼저 class_h.field에 메모리를 할당한다. 2차 배열이어야 하므로 먼저 과목의수+2(학 번,총점) 만큼 char형 이중 포인터로 메모리를 할당 받고, 이것을 다시 for문으로 각 field마다 SUBJECT_SIZE만큼의 포인터로 할당을 받는다. 정적 할당에서의 field[a][b] 와 같다.- 각 학생 데이터마다 field에 과목갯수+2(학번,총점)만큼 int형 포인터로 메모리 할당을 받는다. 그리고 할당 받은 메모리를 초기화 시켜준다.2 )int parse_input(char *s){: 명령어 입력을 해석 한다.- 입력된 명령어를 strtok()함수를 사용해서 공백을 구분자로 나눈다. 문자열의 왼쪽부 분을 추출해서 S-ID,과목명들,TOTAL과 비교해서 s_object(정렬 대상을 가리키는 변수) 에 넣어주고, 그 값이 -1이면 해당 과목이 없다는 뜻이므로 오류 메시지 출력하고 -1 (프로그램 종료)를 리턴해준다. 문자열의 오른쪽 부분을 추출해서 INSERTION, QUICK, HEAP, MERGE과 비교해서 s_method(정렬 방법을 가리키는 변수)에 넣어주 고, 그 값이 -1이면 해당 정렬 방법이 없다는 뜻이므로 오류 메시지 출력하고 -1(프로 그램 종료)값을 리턴 해준다. 정렬 대상과 정렬 방법을 찾았다면 1을 리턴해서 main() 함수에서 적절한 정렬 함수를 호출해서 정렬 시켜준다.