이산수학 C1 프로젝트 7

550 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
550
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

이산수학 C1 프로젝트 7

  1. 1. C1조 과제물 발표 조장 : 09박구남 조원 : 08민영지 09정준용 09최고봉
  2. 2. 과제수행일지 조원소개 조장 박구남소 속 C1 조 자료조사 정준용,민영지 프로그래밍 최고봉 주 제연구제목 Group codes 하프만 코드를 사용하여 압축연구배경 참 고 자 료 과제의 수행 첫째날 2012 년 6 월 13 일 수요일회의 주제 조원 자기소개 및 역할분담, 과제 파악 조장 : 박구남 자료조사 : 정준용, 민영지 프로그래밍 : 최고봉 이상과 같이 이번 프로젝트의 역할분담을 실시했습니다. 첫 수업시간에 문제 파악을 위해 토의를 진행 하면서 각자 역할 분담을 하였습니다. 허프만 코드 개념 ■ 허프만코드 : 일종의 파일 압축 알고리즘회의 내용 텍스트에 나타나는 특정 문자에 대한 빈도수를 이용 자주 사용되는 문자는 짧은 코드를, 자주 사용하지 않는 문자는 긴 코드를 지정 실제 평균 문자 코드 길이를 줄여 압축하는 방법 파일에 사용되는 문자의 사용빈도가 높은 것은 이진 트리의 높은 위치에, 낮은 것은 이진트리의 낮은 위치에 놓아 코드화 허프만 코드는 접두 코드를 회피하여 문자 표현 어떤 코드가 다른 코드의 접두사가 되지 않으면 코드의 길이는 서로 달라도 문자를 표현하는데 지장 없음 이진트리를 생성하여 트리의 왼쪽 종속트리로 갈 때에는 0, 오른쪽 종속트리로 갈 때에는 1로 코드화 허프만 코드는 가장 널리 쓰이는 압축 방법 문자가 나타나는 빈도수에 따라 그 크기를 다르게 하는 것 : 빈도수 의존 코드 모음과 L, R, S, N, T 등과 같이 자주 나타나는 문자들은 더 작은 비트를 할당
  3. 3. ■ 허프만코드 예제각각의 확률이 0.5, 0.3, 0.15, 0.05인 4개의 값 x1, ..., x4가 있다고 가정만일 x1, ..., x4값 각각을 나타내기 위해 코드 값 00, 01, 10, 11을 사용한다면 X값을전송하기 위해 2비트가 필요그러나 만일 x1을 나타내기 위해 0, x2를 나타내기 위해 10, x3을 나타내기 위해 110,x4를 나타내기 위해 111을 사용한다면, 평균 0.5*1 + 0.3*2 + 0.15*3 + 0.05 * 3 =1.7비트가 필요 ■ 허프만코드 생성 방법① 단 하나의 노드만을 가지고 있는 이진 트리와 각 문자를 매핑② 각 트리에 문자들의 빈도수를 할당 : 트리의 가중치(weight) - 내림차순으로 정렬③ 두 개의 가장 작은 가중치를 가지고 있는 트리를 찾아 하나의 트리로 합치고 새로운루트 노드를 만들어 냄 (이 새 트리의 가중치는 합쳐진 두 트리의 가중치의 합)④ 마지막으로 하나의 트리가 남을 때까지 이 과정을 반복⑤ 이 과정이 끝났을 때 원래 노드들의 각각은 마지막 이진 트리의 말단 노드(leaf)가 됨⑥ 이진 트리에서 루트로부터 말단 노드에 이르는 유일한 길(path)이 있게 되고 이 길이허프만 코드가 됨 ( 각 왼쪽 자식 포인터에 0을 할당하고, 오른쪽 자식 포인터에 1을할당해서 결정) - 2 -
  4. 4. ■ 초기 코드 Character Code Frequency Total Bits a 000 10 30 e 001 15 45 i 010 12 36 s 011 3 9 t 100 4 12 space 101 13 39 new line 110 1 3 Total 3 Bits 58 회 174 Bits■ 초기 코드의 이진트리 표현 - 3 -
  5. 5. 둘째날 2012 년 6 월 19 일 화요일회의주제 허프만 코드 알고리즘을 이용하여 프로그램 작성회의내용 허프만 코드를 사용하여 Group Code를 만드는 방법. - 4 -
  6. 6. 결과 발표 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Node { char ch; int freq; }Node; typedef struct Code { int num; char ch; int freq; struct Code *right; struct Code *reft; }Code; Node **arr; int a_size; Node **a_temp; Code **h_code; int c_size = 0; Code **c_temp;프로그램 소스 void InitArr(); void ReInitArr(); void SortingArr(Node **Target); void InitCode(); void Coding(Code **Target,int n); void SortingCode(Code **Target); int MakeCode(Code *Target,Node **k,int i,int n); int main( int argc , char* argv[] ) { FILE*input; char tmp_c; int i,j; Node **result; char c[32]; char temp[32]; if ( argc != 2 || strlen(argv[1]) == 0) { printf("Usage : %s filenamen" , argv[0]); getch(); return 0; } - 5 -
  7. 7. input = fopen(argv[1],"r");if (!input) {fprintf(stderr,"Can not open a file. : %s n",argv[1]);getch();exit(1);}InitArr();while ( !feof(input) ) {tmp_c = fgetc(input);printf("%c",tmp_c);if( tmp_c >= 65 && tmp_c <= 90 )tmp_c += 32;for( i = 0 ; i < a_size ; i++ ) {if( arr[a_size-1]->ch != -1 )ReInitArr();if( arr[i]->ch == tmp_c ) {arr[i]->freq++;break}else if( arr[i]->ch == -1 ) {arr[i]->ch = tmp_c;arr[i]->freq++;c_size++;break}}}printf("n");SortingArr(arr);for( i = 0 ; i < c_size ; i++ )*arr[i] = *a_temp[i];InitCode();Coding(h_code,1);result = (Node **)malloc(c_size*sizeof(Node *));for( i = 0 ; i < c_size ; i++ ) {result[i] = (Node *)malloc(c_size*sizeof(Node));result[i]->freq = 0;result[i]->ch = -1;}MakeCode(h_code[0],result,0,1<<1);for( i = 0, c[0] = 0 ; i < c_size ; i++ ) {printf("%c",result[i]->ch);while( result[i]->freq != 1 ) {if( result[i]->freq & 1 ) {result[i]->freq >>= 1; - 6 -
  8. 8. temp[0] = 1temp[1] = 0;}else {result[i]->freq >>= 1;temp[0] = 0temp[1] = 0;}strcat(temp,c);strcpy(c,temp);}printf(" %sn",c);for( j = 0 ; j < 32 ; j++ )c[j] = 0;}printf("계°e속¼O하CI시½A려·A면¸e 아¾Æ무¹≪키A°나³ª 누´ⓒ르¸£세¼¼요¿a......");getch();}void InitArr() {int i;a_size = 40;arr = (Node **)malloc(a_size*sizeof(Node *));a_temp = (Node **)malloc(a_size*sizeof(Node *));for( i = 0 ; i < a_size ; i++ ) {arr[i] = (Node *)malloc(sizeof(Node));arr[i]->ch = -1;arr[i]->freq = 0;a_temp[i] = (Node *)malloc(a_size*sizeof(Node));a_temp[i]->ch = -1;a_temp[i]->freq = 0;}}void ReInitArr() {int i = a_size;a_size += 5;arr = (Node **)realloc(arr,a_size*sizeof(Node *));for( ; i < a_size ; i++ ) {arr[i] = (Node *)malloc(sizeof(Node));arr[i]->ch = -1;arr[i]->freq = 0;}}void SortingArr(Node **Target) { - 7 -
  9. 9. int x,i;Node *min;min = (Node *)malloc(sizeof(Node));for( x = 0 ; x < a_size ; x++ ) {min->freq = 60000;for( i = 0 ; i < a_size ; i++ ) {if( Target[i]->ch == -1 )breakif( Target[i]->ch == -2 )continueif( ( min->freq > Target[i]->freq ) ) {min->ch = Target[i]->ch;min->freq = Target[i]->freq;}}if( min->freq != 60000 ) {a_temp[x]->ch = min->ch;a_temp[x]->freq = min->freq;}for( i = 0 ; i < a_size ; i++ ) {if( min->ch == Target[i]->ch ) {Target[i]->ch = -2;Target[i]->freq = 60000;}}}}void InitCode() {int i;h_code = (Code **)malloc(sizeof(Code *));c_temp = (Code **)malloc(sizeof(Code *));for( i = 0 ;i < c_size ; i++ ) {h_code[i] = (Code *)malloc(sizeof(Code));h_code[i]->ch = arr[i]->ch;h_code[i]->num = -1;h_code[i]->freq = arr[i]->freq;h_code[i]->right = (Code *)malloc(sizeof(Code));h_code[i]->reft = (Code *)malloc(sizeof(Code));h_code[i]->right = NULL;h_code[i]->reft = NULL;c_temp[i] = (Code *)malloc(sizeof(Code));c_temp[i]->num = -1;c_temp[i]->ch = -1;c_temp[i]->freq = 0;c_temp[i]->reft = (Code *)malloc(sizeof(Code));c_temp[i]->right = (Code *)malloc(sizeof(Code));c_temp[i]->reft = NULL;c_temp[i]->right = NULL;} - 8 -
  10. 10. }void Coding(Code **Target,int n) {Code *tmp;int i;if( n >= c_size )returntmp = (Code *)malloc(sizeof(Code));tmp->reft = (Code *)malloc(sizeof(Code));tmp->right = (Code *)malloc(sizeof(Code));tmp->num = n;tmp->ch = -3;tmp->freq = Target[0]->freq + Target[1]->freq;tmp->reft->ch = Target[0]->ch;tmp->reft->freq = Target[0]->freq;tmp->reft->num = Target[0]->num;tmp->reft->reft = Target[0]->reft;tmp->reft->right = Target[0]->right;tmp->right->ch = Target[1]->ch;tmp->right->freq = Target[1]->freq;tmp->right->num = Target[1]->num;tmp->right->reft = Target[1]->reft;tmp->right->right = Target[1]->right;*Target[0] = *tmp;Target[1]->num = -2;Target[1]->ch = -2;Target[1]->freq = 60000;Target[1]->reft = NULL;Target[1]->right = NULL;SortingCode(Target);for( i = 0 ; i < c_size ; i++ ) {*Target[i] = *c_temp[i];c_temp[i]->num = -1;c_temp[i]->ch = -1;c_temp[i]->freq = 0;c_temp[i]->reft = NULL;c_temp[i]->right = NULL;}free(tmp);Coding(Target,++n);}void SortingCode(Code **Target) {int x,i;Code *min;min = (Code *)malloc(sizeof(Code));for( x = 0 ; x < c_size ; x++ ) {min->freq = 60000;for( i = 0 ; i < c_size ; i++ ) { - 9 -
  11. 11. if( Target[i]->ch == -1 )breakif( Target[i]->ch == -2 && Target[i]->num == -2 )continueif( ( min->freq > Target[i]->freq ) ) {min->num = Target[i]->num;min->ch = Target[i]->ch;min->freq = Target[i]->freq;min->reft = Target[i]->reft;min->right = Target[i]->right;}}if( min->freq != 60000 ) {c_temp[x]->num = min->num;c_temp[x]->ch = min->ch;c_temp[x]->freq = min->freq;c_temp[x]->reft = min->reft;c_temp[x]->right = min->right;}for( i = 0 ; i < c_size ; i++ ) {if( min->ch == Target[i]->ch && min->num == Target[i]->num ) {Target[i]->num = -2;Target[i]->ch = -2;Target[i]->freq = 60000;Target[i]->reft = NULL;Target[i]->right = NULL;}}}}int MakeCode(Code *Target,Node **k,int i,int n) {if( Target->reft == NULL && Target->right == NULL ) {k[i]->ch = Target->ch;k[i]->freq = (n>>1);i++;n = 1;n <<= 1;}else {i = MakeCode(Target->reft,k,i,n<<1);i = MakeCode(Target->right,k,i,(n+1)<<1);}return i;} - 10 -
  12. 12. 최종 반성 - 11 -

×