SlideShare una empresa de Scribd logo
1 de 21
Descargar para leer sin conexión
project #7



  Group Codes



              이산치 수학 B1
                     조장
             20113318 정예린
                     조원
             20093483 백종근
             20093496 윤은영
             20093468 김현호
             20113311 장동규
순서
      •조원별 업무분담
           •일정 계획
           •문제 파악
-문자의 빈도수에 따른 코드를 찾는
     허프만 알고리즘으로 설계
        •알고리즘 계획
            •소스구현
1) 조원별 업무 분담
이름            역할

백종근           보고서 작성, 자료 조사

김현호           자료 조사, 보고서 작성

장동규           알고리즘, 자료조사, 보고서 작성

윤은영           보고서 작성, 자료 조사

정예린           코딩, 자료 조사




2)일정계획
날짜            계획
06.11~06.13   프로젝트에 대한 자료 조사
06.14~06.18   알고리즘을 이용해 소스를 작성
              소스의 잘못된 부분 수정, 최종 보고서 작
06.18~06.20
              성
3)문제파악




1. hamming distance

같은 비트 수를 갖는 2진 부호 사이에 대응되는 비트값이 일치하지 않는 개수. 일반적으로
해밍 거리        d가 d≥2a+1이면 a개의 오류를 정정할 수 있다. A:101011, B:110010, A와 B의
해밍 거리는 3이다.



해밍 코드에서 연속하는 두 숫자 코드 사이의 2진수. 즉, 두 개의 n 비트 2진 부호.
(x1, x2,…, xn), (y1, y2,…, yn)
에 있어서
ㅣx1-y1ㅣ+ㅣx2-y2ㅣ+…+ㅣxn-yn
을 해밍 거리라고 한다. 각 x, y는 2진 부호이면서 1, 0 중 하나의 값을 가지므로
ㅣxi+yiㅣ= xi⊕yi=(xi-yi)2
인 성질을 가진다. 따라서
ㅣx1-y1ㅣ+ㅣx2-y2ㅣ+…+ㅣxn-ynㅣ=(x1-y1)2+(x2-y2)2+…+(xn-yn)2
이 되므로 유클리드 거리의 제곱이 된다.
2. coordinate
어느 한 행과 열의 교차점과 같은 특정 위치를 지정하기 위해 사용되는 1쌍의 값. 컴퓨터
그래픽스(CG)와 화면 표시에서 좌표는 직선상의 점, 네모꼴의 각, 화면상의 픽셀의 위치 등
을 지정하는 데 사용된다. 다른 컴퓨터 응용에서 좌표는 스프레드시트상의 셀, 도표상의 데
이터 포인트, 기억 장치 내의 위치 등을 지정하는 데 사용된다. 좌표의 의미와 배열 등을 규
정하는 체계 또는 표준을 좌표계(coordinate system)라고 한다. 가장 보편적인 데카르트 좌
표계에서는 각 축이 교차하는 점을 좌표를 측정하는 원점으로 하여 2차원 및 3차원의 공간
위에 직사각형의 그리드를 겹쳐 놓는다. 2차원에서는 X축과 Y축의 교차점이 원점이 되고, 3
차원에서는 X축, Y축, Z축의 교차점이 원점이 된다. 목적에 따라 여러 가지 좌표계가 사용된
다.




3. n-tuple
한 릴레이션의 애트리뷰트 개수를 차수(degree)라 하는데, N의 차수를 가진 한 행(行)을 말
한다.




4. huffman code
압축기법의 하나.

가변 길이 코드로 문자의 발생빈도를 검사해 발생 빈도가 높은 문자에 적은 수의 비트를,
빈도수가 적은 문자에 많은 수의 비트를 할당한다.

4)-1 heap
heap은 프로그램이 실행될 때까지는 알 수 없는 가변적인 량만큼의 데이터를 저장하기 위
해, 프로그램의 프로세스가 사용할 수 있도록 미리 예약되어 있는 메인 메모리의 영역이다.
예를 들면, 하나의 프로그램은 처리를 위해 한 명 이상의 사용자로부터 서로 다른 량의 입
력을 받을 수 있으며, 즉시 모든 입력데이터에 대해 처리를 개시한다. 운영체계로부터 이미
확보된 일정량의 heap 저장 공간을 가지고 있으면, 저장과 관련된 처리를 좀 더 쉽게 할 수
있으며, 일반적으로 필요할 때마다 운영체계에게 매번 저장 공간을 요청하는 것보다 빠르다.
프로세스는 필요할 때 heap 블록을 요구하고, 더 이상 필요 없을 때 반환하며, 이따금씩 "
자투리 모으기"를 수행함으로써 자신에게 할당된 heap을 관리한다. 여기서 자투리 모으기란
더 이상 사용되지 않는 블록들을 사용 가능한 상태로 만들고, 또한 heap 내의 사용 가능한
공간을 인지함으로써 사용되지 않은 작은 조각들이 낭비되지 않도록 하는 것을 말한다.
4)-2 허프만 트리 예




4)알고리즘 계획
1. 문자열을 검사해 각 문자의 빈도수를 조사해 우선순위 큐에 집어넣는다.
 (빈도수가 낮을수록 우선순위는 높다)

2. 큐에서 2개의 노드를 추출 이진트리로 만들고 루트는 두 노드의 빈도수 합으로 한다.

3. 생성된 이진트리의 루트노드 x를   다시 우선순위 큐에 삽입
 이때 x의 빈도수는 x의 자식노드의 빈도수 합이다.

4. 모든 원소가 이진트리의 원소가 될 때 까지 2,3 과정 반복

5. 트리가 완성되면 루트를 기준으로 왼쪽은0, 오른쪽은 1의 가중치를 부여해 트리의 노드
 에 코드를 부여
5)소스 구현
-참고소스 및 분석
5)-1
//Deap Class and Huffman Tree Library
//created by Kim Yongmook ( http://moogi.new21.org )
//Originically created on June 10, 2003


#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>


typedef int BOOL;
#define ASSERT(p) assert(p)


template<typename TYPE>
inline void Swap(TYPE &a, TYPE& b)
{
          TYPE c; c=a; a=b; b=c;
}


//Deap data structure * * * * * * * * * * * *
template<typename TYPE, typename ARG_TYPE>
class CDeap {
          TYPE *m_pData; int m_nSize, m_nCount;
          static int GetAdjacentNode(int x, int *dir=NULL)
          {
                  int i; //x must be equal to or greater than 2!
                  //2->6, 15->11, 7->5 converter
                  //dir: 0 if 2,4,5,10 (left side, that is min heap), else 3 7 13 (right side,
max heap)
                  for(i=31;(x&(1<<i))==0;i--); if(dir) *dir=!!(x&(1<<(i-1)));
                  return x^(1<<(i-1));
          }
          void AddHelper(ARG_TYPE p, int pos);
public:
          CDeap(int siz): m_nSize(siz), m_nCount(2)
          {
m_pData=new TYPE[siz]; m_pData-=2; //0, 1 인덱스는 쓰이지 않고 있다.
         }
         ~CDeap() { delete [](m_pData+2); }


         int GetSize() const { return m_nSize; }
         int GetCount() const { return m_nCount-2; }
         //WARN: 최소한 자료가 하나는 있어야 이들 함수를 쓸 수 있다
         TYPE GetMax() const { ASSERT(m_nCount>2); return m_pData[m_nCount>3 ? 3:2];
}
         TYPE& GetMax() { ASSERT(m_nCount>2); return m_pData[m_nCount>3 ? 3:2]; }
         TYPE GetMin() const { ASSERT(m_nCount>2); return m_pData[2]; }
         TYPE& GetMin() { ASSERT(m_nCount>2); return m_pData[2]; }
         BOOL Add(ARG_TYPE p, int policy=-1);
         BOOL RemoveMax();
         BOOL RemoveMin();
         void Display() const; //디버깅용
};


//DEAP의 정의와, 양쪽 힙의 특성을 유지하게끔, p 위치에 삽입된 원소를
//요리조리 옮겨주는 함수
//단, pos가 MIN 쪽일 때는 트리의 맨 밑바닥 번호여야 하고, (즉 (pos<<1)>=m_nCount )
//MAX 쪽일 때는 자식이 최대 하나만 있어야 한다.
template<typename TYPE, typename ARG_TYPE>
void CDeap<TYPE, ARG_TYPE>::AddHelper(ARG_TYPE p, int pos)
{
         int adj, dir, root; //ASSERT((pos<<1)>=m_nCount);
         m_pData[pos]=p;
         if(m_nCount>3) { //원소가 둘 이상이 되면
                 adj=GetAdjacentNode(pos, &dir);


                 //이제 우리가 어느 쪽이냐에 따라 adj 값을 보정한다.
                 if(dir) {
                             //우리가 max쪽이면 상대는 min. 우리가 상대의 자식들보다도 큰
지 검사해야 한다.
                             if((adj<<1)<m_nCount && m_pData[adj]<m_pData[adj<<1]) {
                                    adj<<=1; //two children
                                    if(adj+1<m_nCount && m_pData[adj]<m_pData[adj+1])
adj++;
                             }
                 }
                 else //우리가 min쪽이므로 짝이 존재하지 않을 수도 있다.
if(adj>=m_nCount) adj>>=1; //짝이 존재하는 곳까지 부모 노드
로...
               //우리가 왼쪽에 있는데(min side. dir=0, pos) 우리 값이 오른쪽(adj)보다
더 크면
               //두 값을 맞바꾸고, adj가 우리 원소가 들어가는 번호가 된다.
               if(dir^(m_pData[pos]>m_pData[adj])) {
                        Swap(m_pData[adj], m_pData[pos]); dir^=1;
               }
               else adj=pos;
               ASSERT(adj>=2 && adj<=m_nCount);


               //이제 우리 원소가 소속된 쪽(min or max)에 맞게 힙을 재정렬한다.
               while(adj>3) {
                        root=adj>>1;
                        //루트가 현재보다 더 크고 최소 트리 모드이거나
                        //루트가 현재보다 작고 최대 트리 모드이면 서로 위치를 바꾼다
:)
                        if( (m_pData[root]>m_pData[adj])^dir ) {
                                  Swap(m_pData[adj], m_pData[root]); adj=root;
                        }
                        else break;
               }
       }
}


//policy: 원소 개수가 m_nSize를 넘어갈 때의 정책:
//0: 최소값을 경신. 1: 최대값을 경신.
//-1: 그냥 에러를 반환한다.
template<typename TYPE, typename ARG_TYPE>
BOOL CDeap<TYPE, ARG_TYPE>::Add(ARG_TYPE p, int policy)
{
       if(GetCount()==m_nSize)
               switch(policy) {
               case 0: if(GetMax()<p) return false; else RemoveMax(); break;
               case 1: if(GetMin()>p) return false; else RemoveMin(); break;
               default: return false;
               }
       m_nCount++; AddHelper(p, m_nCount-1); return true;
}


template<typename TYPE, typename ARG_TYPE>
BOOL CDeap<TYPE, ARG_TYPE>::RemoveMin()
{
        int i,j;
        if(m_nCount==2) return false; //no data to delete
        for(i=2;(i<<1)<m_nCount;m_pData[i]=m_pData[j], i=j) {
                    j=(i<<1); if(j+1<m_nCount && m_pData[j+1]<m_pData[j]) j++;
        }
        //이제 남은 자리에다 마지막 원소를 삽입한다.
        m_nCount--; AddHelper(m_pData[m_nCount], i); return true;
}


template<typename TYPE, typename ARG_TYPE>
BOOL CDeap<TYPE, ARG_TYPE>::RemoveMax()
{
        int i,j;
        switch(m_nCount) {
        case 2: return false; //no data to delete
        case 4: case 3: m_nCount--; return true; //simply decrease the count
        }
        for(i=3;(i<<1)<m_nCount;m_pData[i]=m_pData[j], i=j) {
                    j=(i<<1); if(j+1<m_nCount && m_pData[j+1]>m_pData[j]) j++;
        }
        m_nCount--; //이제 남은 자리에다 마지막 원소를 삽입한다.
        if(m_nCount==i) i>>=1; //min쪽의 밑바닥 검사를 위한 조치이다!!
        AddHelper(m_pData[m_nCount], i); return true;
}


template<typename TYPE, typename ARG_TYPE>
void CDeap<TYPE, ARG_TYPE>::Display() const
{
        int x,a=1,b=0,c=0;
        for(x=2;x<m_nCount;x++) {
                    printf("%d ", m_pData[x]);
                    c++; if(c==a) { printf("| "), c=0; if(b==1) a<<=1; b^=1; }
        }
        puts("");
}


//Huffman tree library * * * * * * * * * * * *
#define NOPARENT 999999
class CHuffman {
struct ENTRY {
                      //index 멤버는 배열에서는 이 원소의 부모 노드 번호로,
                      //min 힙 안에서는 이 원소의 원래 배열 번호를 가리킨다. 다용도임.
                      int index, value;
                      ENTRY() {}
                      ENTRY(int a, int b): index(a), value(b) {}
                      operator int() const { return value; }
             };
             int m_nCount;
             ENTRY *m_pEnt;
             CDeap<ENTRY, const ENTRY&> m_Heap;
public:
             CHuffman(const int *data, int count): m_Heap(count), m_nCount(count)
             {
                      int i; m_pEnt=new ENTRY[count*2];
                      for(i=0;i<count;i++) {
                                 m_pEnt[i]=ENTRY(NOPARENT,         data[i]);   m_Heap.Add(ENTRY(i,
data[i]));
                      }
             }
             ~CHuffman() { delete []m_pEnt; }
             void Solve();
             //result retrieve
             int GetCode(int n, char *cod=NULL) const;
};


//허프만 나무를 n log n 시간만에 구성한다. 힙 덕분에 가능한 복잡도임
void CHuffman::Solve()
{
             int lp=m_nCount; ENTRY a,b;
             //가장 작은 놈 둘을 빼낸다.
             while(m_Heap.GetCount()>=2) {
                      a=m_Heap.GetMin(); m_Heap.RemoveMin();
                      b=m_Heap.GetMin(); m_Heap.RemoveMin();
                      m_pEnt[a.index].index=-lp; //left (0) side
                      m_pEnt[b.index].index=lp; //right (1) side
                      m_pEnt[lp]=ENTRY(NOPARENT, a.value+b.value);
                      m_Heap.Add(ENTRY(lp, a.value+b.value));
                      lp++;
             }
}
//actual binary code, plus its length as the return value
int CHuffman::GetCode(int n, char *cod) const
{
        int j; char *cod2=cod;
        for(j=0;m_pEnt[n].index!=NOPARENT;j++) {
                    if(cod) { *cod='0'+(m_pEnt[n].index>0); cod++; }
                    n=abs(m_pEnt[n].index);
        }
        if(cod) { *cod=0; _strrev(cod2); } //reverse the order. _strrev는 표준 함수가 아니
기 때문에 지원하지 않는 컴파일러도 있음.
        return j;
}


//Demonstrations * * * * * * * * * * * *
void DeapTest()
{
        CDeap<int, int> pk(150); unsigned seee; int i,j, bef,arr[500];
        seee=time(0); srand(seee);
        for(i=0;i<500;i++) arr[i]=i+1;
        for(j=0;j<3;j++) for(i=0;i<200;i++) Swap(arr[i], arr[rand()%100]);
        printf("Original order: ");
        for(i=0;i<150;i++) printf("%d ", arr[i]); puts("n");
        for(i=0;i<150;i++) pk.Add(arr[i], 0);
        printf("Heap form: "); pk.Display(); puts("");
        printf("Min form: "); bef=-1;
        while(pk.GetCount()>0) {
                    printf("%d ", pk.GetMin()); ASSERT(bef<=pk.GetMin());
                    bef=pk.GetMin(); pk.RemoveMin();
        }
        puts("n");
        for(i=0;i<150;i++) pk.Add(arr[i], 1);
        printf("Max form: "); bef=99999;
        while(pk.GetCount()>0) {
                    printf("%d ", pk.GetMax()); ASSERT(bef>=pk.GetMax());
                    bef=pk.GetMax(); pk.RemoveMax();
        }
}


void HuffmanTree()
{
int seq[26]={
                     1532, 418, 729, 902, 2503, 359, 614, 460, 1765, 67, 530, 1317, 580,
1148, 1266, 549,
                     51, 1100, 2325, 1277, 840, 280, 249, 137, 850, 214};
           int i, sum; char buf[24];
           CHuffman huf(seq, 26); huf.Solve();
           for(i=sum=0;i<26;i++) {
                     printf("%c's code size is %d - ", i+'A', huf.GetCode(i, buf));
                     puts(buf);
                     sum+=huf.GetCode(i)*seq[i];
           }
           printf("Compression size %dn", sum);
           for(i=sum=0;i<26;i++) sum+=seq[i]*5;
           printf("UnCompression size %dn", sum);
}


int main()
{
           puts("Sorting with Deap:"); DeapTest();
           puts("nnHuffman tree:"); HuffmanTree();
           return 0;
}




5)-2
#include<stdio.h>
#include<stdlib.h>


    struct sort
{
           char c;
           double d;
}; //문자와 확률을 넘겨 받는 구초제형 선언



#define MAX_ELEMENT 100
typedef struct TreeNode{


    int weight;


    struct TreeNode *left_child;


    struct TreeNode *right_child;


}TreeNode;


typedef struct element{


    TreeNode *ptree;


    int key;


}element;


typedef struct HeapType{


    element heap[MAX_ELEMENT];


    int heap_size;


}HeapType;


void print(TreeNode *root);


void init(HeapType *h)


{


    h->heap_size=0;


}


//삽입함수
void insert_min_heap(HeapType *h, element item)


{


    int i;


    i = ++(h->heap_size);




    //트리를거슬러올라가면서부모노드와비교하는과정그래야인덱스를찾지


    while((i != 1) && (item.key < h->heap[i/2].key)){


         h->heap[i] = h->heap[i/2];


         i /= 2;


    }


    h->heap[i] = item;      //새로운노드삽입


}


//삭제함수


element delete_min_heap(HeapType *h)


{


    int parent, child;


    element item, temp;
item = h->heap[1];


    temp = h->heap[(h->heap_size)--];


    parent = 1;


    child = 2;




    while(child <= h->heap_size){


        //현재노드의자식노드중더작은자식노드를찾는다.


        if((child< h->heap_size) && (h->heap[child].key > h->heap[child+1].key))


            child++;


        if(temp.key <= h->heap[child].key) break;


        //한단계아래로이동


        h->heap[parent] = h->heap[child];


        parent = child;


        child *= 2;


    }




    h->heap[parent] = temp;


    return item;


}
//이진트리생성함수


TreeNode *make_tree(TreeNode *left, TreeNode *right)


{


    TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode));


    if(node == NULL){


        fprintf(stderr,"메모리할당에러n");


        exit(1);


    }


    node->left_child = left;


    node->right_child = right;


    return node;


}


//이진트리제거함수


void destroy_tree(TreeNode *root)


{


    if(root == NULL) return;


    destroy_tree(root->left_child);


    destroy_tree(root->right_child);
free(root);


}


//허프만코드생성함수


void huffman_tree(struct sort arr[], int n)


{


    int i;


    HeapType heap;


    element e, e1, e2;


    TreeNode *node, *x;


    //int k;


    init(&heap);


    for(i=0;i<n;i++){


         node = make_tree(NULL,NULL);


         e.key = node->weight = arr[i];


         e.ptree = node;


         insert_min_heap(&heap, e);


    }


    //for(i=0;i<=n;i++)


    //       printf("%d->",heap.heap[i].key);
for(i=1;i<n;i++){


    //최소값을가지는두개의노드를삭제


    e1 = delete_min_heap(&heap);


    /*printf("방금힙에서꺼낸것: %dn", e1.key);


    for(k=1;k<n;k++)


         printf("꺼내고난후에힙배열: %dn",heap.heap[k].key);*/


    e2 = delete_min_heap(&heap);


    /*printf("그다음힙에서꺼낸것: %dn", e2.key);


    for(k=1;k<n;k++)


         printf("꺼내고난후에힙배열: %dn",heap.heap[k].key);*/


    //두개의노드를합친다.


    x = make_tree(e1.ptree, e2.ptree);


    e.key = x->weight = e1.key + e2.key;


    //printf("e.key=%d, x->weight=%dn",e.key, x->weight);


    e.ptree = x;


    insert_min_heap(&heap, e);


    //printf("%dn", heap.heap[4].key);


}
e = delete_min_heap(&heap);    //최종트리


    //print(e.ptree);


//원래나오는최종트리heap배열엔: 4 6 12 15 8



    destroy_tree(e.ptree);




}


void print(TreeNode *root)


{


    if(root){


    print(root->left_child);


    print(root->right_child);


    printf("(%d)",root->weight);


    }


}


void main()


{
        struct sort arr[100],; //구조체형 배열을 선언하여 입력받음
        int i=0,j=0,m;
for(i=0;i<100;i++)
    {
               for(j=0;j<100;j++)
               {
                       arr[i].c='0';
                       arr[i].d='0';
               }
    }
    j=0;
    while(j!=6)
    {
               scanf("%c %lfn",&arr[j].c,&arr[j].d);
               j++;
    }


    for(i=0;i<j;i++)
    {
                       printf("%c %fn",arr[i].c,arr[i].d);
                       //printf("i=%d",i);
    }


        huffman_tree(arr, 5);


}

Más contenido relacionado

La actualidad más candente

빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)SeongHyun Ahn
 
이산수학 C1 프로젝트 7
이산수학 C1 프로젝트 7이산수학 C1 프로젝트 7
이산수학 C1 프로젝트 7pkok15
 
2012 Ds A1 05
2012 Ds A1 052012 Ds A1 05
2012 Ds A1 05seonhyung
 
알고리즘과 자료구조
알고리즘과 자료구조알고리즘과 자료구조
알고리즘과 자료구조영기 김
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀beom kyun choi
 
알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdolsseungdols
 
Project#3 How Fast Can We Sort Hwp
Project#3 How Fast Can We Sort HwpProject#3 How Fast Can We Sort Hwp
Project#3 How Fast Can We Sort HwpKimjeongmoo
 
Computational Complexity
Computational ComplexityComputational Complexity
Computational Complexityskku_npc
 
Mathematics
MathematicsMathematics
Mathematicsskku_npc
 
자료구조 Project5
자료구조 Project5자료구조 Project5
자료구조 Project5KoChungWook
 
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)Tae Young Lee
 
집단지성 프로그래밍 03-군집발견-03
집단지성 프로그래밍 03-군집발견-03집단지성 프로그래밍 03-군집발견-03
집단지성 프로그래밍 03-군집발견-03Kwang Woo NAM
 
Python machine learning Ch.4
Python machine learning Ch.4Python machine learning Ch.4
Python machine learning Ch.4PartPrime
 
Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석용 최
 
파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301Yong Joon Moon
 
영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출동윤 이
 

La actualidad más candente (20)

빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)빠르게 활용하는 파이썬3 스터디(ch1~4)
빠르게 활용하는 파이썬3 스터디(ch1~4)
 
이산수학 C1 프로젝트 7
이산수학 C1 프로젝트 7이산수학 C1 프로젝트 7
이산수학 C1 프로젝트 7
 
2012 Ds A1 05
2012 Ds A1 052012 Ds A1 05
2012 Ds A1 05
 
이산수학07
이산수학07이산수학07
이산수학07
 
3콤비네이션
3콤비네이션3콤비네이션
3콤비네이션
 
알고리즘과 자료구조
알고리즘과 자료구조알고리즘과 자료구조
알고리즘과 자료구조
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀
 
알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols알고리즘 스터디(정렬) Seungdols
알고리즘 스터디(정렬) Seungdols
 
Project#3 How Fast Can We Sort Hwp
Project#3 How Fast Can We Sort HwpProject#3 How Fast Can We Sort Hwp
Project#3 How Fast Can We Sort Hwp
 
Computational Complexity
Computational ComplexityComputational Complexity
Computational Complexity
 
Mathematics
MathematicsMathematics
Mathematics
 
자료구조 Project5
자료구조 Project5자료구조 Project5
자료구조 Project5
 
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
파이썬 데이터과학 레벨2 - 데이터 시각화와 실전 데이터분석, 그리고 머신러닝 입문 (2020년 이태영)
 
집단지성 프로그래밍 03-군집발견-03
집단지성 프로그래밍 03-군집발견-03집단지성 프로그래밍 03-군집발견-03
집단지성 프로그래밍 03-군집발견-03
 
Python machine learning Ch.4
Python machine learning Ch.4Python machine learning Ch.4
Python machine learning Ch.4
 
Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석Python 활용: 이미지 처리와 데이터 분석
Python 활용: 이미지 처리와 데이터 분석
 
파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301
 
영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출영상 데이터의 처리와 정보의 추출
영상 데이터의 처리와 정보의 추출
 
강의자료 2
강의자료 2강의자료 2
강의자료 2
 
자료구조03
자료구조03자료구조03
자료구조03
 

Similar a 2012 Dm 07

자료구조 Project6
자료구조 Project6자료구조 Project6
자료구조 Project6KoChungWook
 
자료구조 프로젝트
자료구조 프로젝트자료구조 프로젝트
자료구조 프로젝트hyungoh kim
 
자료구조5보고서
자료구조5보고서자료구조5보고서
자료구조5보고서KimChangHoen
 
Project#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpProject#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpKimjeongmoo
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdfjinwookhong
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdfkd19h
 
자료구조 Project1
자료구조 Project1자료구조 Project1
자료구조 Project1KoChungWook
 
2012 Ds B2 02
2012 Ds B2 022012 Ds B2 02
2012 Ds B2 02chl132435
 
파이썬 스터디 2주차
파이썬 스터디 2주차파이썬 스터디 2주차
파이썬 스터디 2주차Han Sung Kim
 
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기Ki-Hwan Kim
 
14장 - 15장 예외처리, 템플릿
14장 - 15장 예외처리, 템플릿14장 - 15장 예외처리, 템플릿
14장 - 15장 예외처리, 템플릿유석 남
 
6장 표현식 및 문장
6장 표현식 및 문장6장 표현식 및 문장
6장 표현식 및 문장재정 이
 
2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdf2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdfkd19h
 
2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdf2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdfjinwookhong
 
이산치 과제7
이산치 과제7이산치 과제7
이산치 과제7mil23
 

Similar a 2012 Dm 07 (20)

자료구조 Project6
자료구조 Project6자료구조 Project6
자료구조 Project6
 
자료구조 프로젝트
자료구조 프로젝트자료구조 프로젝트
자료구조 프로젝트
 
자료구조5보고서
자료구조5보고서자료구조5보고서
자료구조5보고서
 
Project#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 HwpProject#5 최단거리 찾기 D0 Hwp
Project#5 최단거리 찾기 D0 Hwp
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf
 
이산치2번
이산치2번이산치2번
이산치2번
 
2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf2012 Dm A0 02 Pdf
2012 Dm A0 02 Pdf
 
자료구조 Project1
자료구조 Project1자료구조 Project1
자료구조 Project1
 
2012 Ds B2 02
2012 Ds B2 022012 Ds B2 02
2012 Ds B2 02
 
파이썬 스터디 2주차
파이썬 스터디 2주차파이썬 스터디 2주차
파이썬 스터디 2주차
 
2012 Ds 01
2012 Ds 012012 Ds 01
2012 Ds 01
 
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기
 
14장 - 15장 예외처리, 템플릿
14장 - 15장 예외처리, 템플릿14장 - 15장 예외처리, 템플릿
14장 - 15장 예외처리, 템플릿
 
HI-ARC PS 101
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101
 
06장 함수
06장 함수06장 함수
06장 함수
 
6장 표현식 및 문장
6장 표현식 및 문장6장 표현식 및 문장
6장 표현식 및 문장
 
2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdf2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdf
 
2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdf2012 Dm A0 07 Pdf
2012 Dm A0 07 Pdf
 
이산치 과제7
이산치 과제7이산치 과제7
이산치 과제7
 
자료구조02
자료구조02자료구조02
자료구조02
 

Más de Jungyerin

Más de Jungyerin (7)

2012 Ds 05
2012 Ds 052012 Ds 05
2012 Ds 05
 
2012 Ds 04
2012 Ds 042012 Ds 04
2012 Ds 04
 
2012 Ds 03
2012 Ds 032012 Ds 03
2012 Ds 03
 
2012 Ds 02
2012 Ds 022012 Ds 02
2012 Ds 02
 
2012 Dm 04
2012 Dm 042012 Dm 04
2012 Dm 04
 
2012 Dm 02
2012 Dm 022012 Dm 02
2012 Dm 02
 
2012 Dm 01
2012 Dm 012012 Dm 01
2012 Dm 01
 

2012 Dm 07

  • 1. project #7 Group Codes 이산치 수학 B1 조장 20113318 정예린 조원 20093483 백종근 20093496 윤은영 20093468 김현호 20113311 장동규
  • 2. 순서 •조원별 업무분담 •일정 계획 •문제 파악 -문자의 빈도수에 따른 코드를 찾는 허프만 알고리즘으로 설계 •알고리즘 계획 •소스구현
  • 3. 1) 조원별 업무 분담 이름 역할 백종근 보고서 작성, 자료 조사 김현호 자료 조사, 보고서 작성 장동규 알고리즘, 자료조사, 보고서 작성 윤은영 보고서 작성, 자료 조사 정예린 코딩, 자료 조사 2)일정계획 날짜 계획 06.11~06.13 프로젝트에 대한 자료 조사 06.14~06.18 알고리즘을 이용해 소스를 작성 소스의 잘못된 부분 수정, 최종 보고서 작 06.18~06.20 성
  • 4. 3)문제파악 1. hamming distance 같은 비트 수를 갖는 2진 부호 사이에 대응되는 비트값이 일치하지 않는 개수. 일반적으로 해밍 거리 d가 d≥2a+1이면 a개의 오류를 정정할 수 있다. A:101011, B:110010, A와 B의 해밍 거리는 3이다. 해밍 코드에서 연속하는 두 숫자 코드 사이의 2진수. 즉, 두 개의 n 비트 2진 부호. (x1, x2,…, xn), (y1, y2,…, yn) 에 있어서 ㅣx1-y1ㅣ+ㅣx2-y2ㅣ+…+ㅣxn-yn 을 해밍 거리라고 한다. 각 x, y는 2진 부호이면서 1, 0 중 하나의 값을 가지므로 ㅣxi+yiㅣ= xi⊕yi=(xi-yi)2 인 성질을 가진다. 따라서 ㅣx1-y1ㅣ+ㅣx2-y2ㅣ+…+ㅣxn-ynㅣ=(x1-y1)2+(x2-y2)2+…+(xn-yn)2 이 되므로 유클리드 거리의 제곱이 된다.
  • 5. 2. coordinate 어느 한 행과 열의 교차점과 같은 특정 위치를 지정하기 위해 사용되는 1쌍의 값. 컴퓨터 그래픽스(CG)와 화면 표시에서 좌표는 직선상의 점, 네모꼴의 각, 화면상의 픽셀의 위치 등 을 지정하는 데 사용된다. 다른 컴퓨터 응용에서 좌표는 스프레드시트상의 셀, 도표상의 데 이터 포인트, 기억 장치 내의 위치 등을 지정하는 데 사용된다. 좌표의 의미와 배열 등을 규 정하는 체계 또는 표준을 좌표계(coordinate system)라고 한다. 가장 보편적인 데카르트 좌 표계에서는 각 축이 교차하는 점을 좌표를 측정하는 원점으로 하여 2차원 및 3차원의 공간 위에 직사각형의 그리드를 겹쳐 놓는다. 2차원에서는 X축과 Y축의 교차점이 원점이 되고, 3 차원에서는 X축, Y축, Z축의 교차점이 원점이 된다. 목적에 따라 여러 가지 좌표계가 사용된 다. 3. n-tuple 한 릴레이션의 애트리뷰트 개수를 차수(degree)라 하는데, N의 차수를 가진 한 행(行)을 말 한다. 4. huffman code 압축기법의 하나. 가변 길이 코드로 문자의 발생빈도를 검사해 발생 빈도가 높은 문자에 적은 수의 비트를, 빈도수가 적은 문자에 많은 수의 비트를 할당한다. 4)-1 heap heap은 프로그램이 실행될 때까지는 알 수 없는 가변적인 량만큼의 데이터를 저장하기 위 해, 프로그램의 프로세스가 사용할 수 있도록 미리 예약되어 있는 메인 메모리의 영역이다. 예를 들면, 하나의 프로그램은 처리를 위해 한 명 이상의 사용자로부터 서로 다른 량의 입 력을 받을 수 있으며, 즉시 모든 입력데이터에 대해 처리를 개시한다. 운영체계로부터 이미 확보된 일정량의 heap 저장 공간을 가지고 있으면, 저장과 관련된 처리를 좀 더 쉽게 할 수 있으며, 일반적으로 필요할 때마다 운영체계에게 매번 저장 공간을 요청하는 것보다 빠르다. 프로세스는 필요할 때 heap 블록을 요구하고, 더 이상 필요 없을 때 반환하며, 이따금씩 " 자투리 모으기"를 수행함으로써 자신에게 할당된 heap을 관리한다. 여기서 자투리 모으기란 더 이상 사용되지 않는 블록들을 사용 가능한 상태로 만들고, 또한 heap 내의 사용 가능한 공간을 인지함으로써 사용되지 않은 작은 조각들이 낭비되지 않도록 하는 것을 말한다.
  • 6. 4)-2 허프만 트리 예 4)알고리즘 계획 1. 문자열을 검사해 각 문자의 빈도수를 조사해 우선순위 큐에 집어넣는다. (빈도수가 낮을수록 우선순위는 높다) 2. 큐에서 2개의 노드를 추출 이진트리로 만들고 루트는 두 노드의 빈도수 합으로 한다. 3. 생성된 이진트리의 루트노드 x를 다시 우선순위 큐에 삽입 이때 x의 빈도수는 x의 자식노드의 빈도수 합이다. 4. 모든 원소가 이진트리의 원소가 될 때 까지 2,3 과정 반복 5. 트리가 완성되면 루트를 기준으로 왼쪽은0, 오른쪽은 1의 가중치를 부여해 트리의 노드 에 코드를 부여
  • 7. 5)소스 구현 -참고소스 및 분석 5)-1 //Deap Class and Huffman Tree Library //created by Kim Yongmook ( http://moogi.new21.org ) //Originically created on June 10, 2003 #include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h> #include <assert.h> typedef int BOOL; #define ASSERT(p) assert(p) template<typename TYPE> inline void Swap(TYPE &a, TYPE& b) { TYPE c; c=a; a=b; b=c; } //Deap data structure * * * * * * * * * * * * template<typename TYPE, typename ARG_TYPE> class CDeap { TYPE *m_pData; int m_nSize, m_nCount; static int GetAdjacentNode(int x, int *dir=NULL) { int i; //x must be equal to or greater than 2! //2->6, 15->11, 7->5 converter //dir: 0 if 2,4,5,10 (left side, that is min heap), else 3 7 13 (right side, max heap) for(i=31;(x&(1<<i))==0;i--); if(dir) *dir=!!(x&(1<<(i-1))); return x^(1<<(i-1)); } void AddHelper(ARG_TYPE p, int pos); public: CDeap(int siz): m_nSize(siz), m_nCount(2) {
  • 8. m_pData=new TYPE[siz]; m_pData-=2; //0, 1 인덱스는 쓰이지 않고 있다. } ~CDeap() { delete [](m_pData+2); } int GetSize() const { return m_nSize; } int GetCount() const { return m_nCount-2; } //WARN: 최소한 자료가 하나는 있어야 이들 함수를 쓸 수 있다 TYPE GetMax() const { ASSERT(m_nCount>2); return m_pData[m_nCount>3 ? 3:2]; } TYPE& GetMax() { ASSERT(m_nCount>2); return m_pData[m_nCount>3 ? 3:2]; } TYPE GetMin() const { ASSERT(m_nCount>2); return m_pData[2]; } TYPE& GetMin() { ASSERT(m_nCount>2); return m_pData[2]; } BOOL Add(ARG_TYPE p, int policy=-1); BOOL RemoveMax(); BOOL RemoveMin(); void Display() const; //디버깅용 }; //DEAP의 정의와, 양쪽 힙의 특성을 유지하게끔, p 위치에 삽입된 원소를 //요리조리 옮겨주는 함수 //단, pos가 MIN 쪽일 때는 트리의 맨 밑바닥 번호여야 하고, (즉 (pos<<1)>=m_nCount ) //MAX 쪽일 때는 자식이 최대 하나만 있어야 한다. template<typename TYPE, typename ARG_TYPE> void CDeap<TYPE, ARG_TYPE>::AddHelper(ARG_TYPE p, int pos) { int adj, dir, root; //ASSERT((pos<<1)>=m_nCount); m_pData[pos]=p; if(m_nCount>3) { //원소가 둘 이상이 되면 adj=GetAdjacentNode(pos, &dir); //이제 우리가 어느 쪽이냐에 따라 adj 값을 보정한다. if(dir) { //우리가 max쪽이면 상대는 min. 우리가 상대의 자식들보다도 큰 지 검사해야 한다. if((adj<<1)<m_nCount && m_pData[adj]<m_pData[adj<<1]) { adj<<=1; //two children if(adj+1<m_nCount && m_pData[adj]<m_pData[adj+1]) adj++; } } else //우리가 min쪽이므로 짝이 존재하지 않을 수도 있다.
  • 9. if(adj>=m_nCount) adj>>=1; //짝이 존재하는 곳까지 부모 노드 로... //우리가 왼쪽에 있는데(min side. dir=0, pos) 우리 값이 오른쪽(adj)보다 더 크면 //두 값을 맞바꾸고, adj가 우리 원소가 들어가는 번호가 된다. if(dir^(m_pData[pos]>m_pData[adj])) { Swap(m_pData[adj], m_pData[pos]); dir^=1; } else adj=pos; ASSERT(adj>=2 && adj<=m_nCount); //이제 우리 원소가 소속된 쪽(min or max)에 맞게 힙을 재정렬한다. while(adj>3) { root=adj>>1; //루트가 현재보다 더 크고 최소 트리 모드이거나 //루트가 현재보다 작고 최대 트리 모드이면 서로 위치를 바꾼다 :) if( (m_pData[root]>m_pData[adj])^dir ) { Swap(m_pData[adj], m_pData[root]); adj=root; } else break; } } } //policy: 원소 개수가 m_nSize를 넘어갈 때의 정책: //0: 최소값을 경신. 1: 최대값을 경신. //-1: 그냥 에러를 반환한다. template<typename TYPE, typename ARG_TYPE> BOOL CDeap<TYPE, ARG_TYPE>::Add(ARG_TYPE p, int policy) { if(GetCount()==m_nSize) switch(policy) { case 0: if(GetMax()<p) return false; else RemoveMax(); break; case 1: if(GetMin()>p) return false; else RemoveMin(); break; default: return false; } m_nCount++; AddHelper(p, m_nCount-1); return true; } template<typename TYPE, typename ARG_TYPE>
  • 10. BOOL CDeap<TYPE, ARG_TYPE>::RemoveMin() { int i,j; if(m_nCount==2) return false; //no data to delete for(i=2;(i<<1)<m_nCount;m_pData[i]=m_pData[j], i=j) { j=(i<<1); if(j+1<m_nCount && m_pData[j+1]<m_pData[j]) j++; } //이제 남은 자리에다 마지막 원소를 삽입한다. m_nCount--; AddHelper(m_pData[m_nCount], i); return true; } template<typename TYPE, typename ARG_TYPE> BOOL CDeap<TYPE, ARG_TYPE>::RemoveMax() { int i,j; switch(m_nCount) { case 2: return false; //no data to delete case 4: case 3: m_nCount--; return true; //simply decrease the count } for(i=3;(i<<1)<m_nCount;m_pData[i]=m_pData[j], i=j) { j=(i<<1); if(j+1<m_nCount && m_pData[j+1]>m_pData[j]) j++; } m_nCount--; //이제 남은 자리에다 마지막 원소를 삽입한다. if(m_nCount==i) i>>=1; //min쪽의 밑바닥 검사를 위한 조치이다!! AddHelper(m_pData[m_nCount], i); return true; } template<typename TYPE, typename ARG_TYPE> void CDeap<TYPE, ARG_TYPE>::Display() const { int x,a=1,b=0,c=0; for(x=2;x<m_nCount;x++) { printf("%d ", m_pData[x]); c++; if(c==a) { printf("| "), c=0; if(b==1) a<<=1; b^=1; } } puts(""); } //Huffman tree library * * * * * * * * * * * * #define NOPARENT 999999 class CHuffman {
  • 11. struct ENTRY { //index 멤버는 배열에서는 이 원소의 부모 노드 번호로, //min 힙 안에서는 이 원소의 원래 배열 번호를 가리킨다. 다용도임. int index, value; ENTRY() {} ENTRY(int a, int b): index(a), value(b) {} operator int() const { return value; } }; int m_nCount; ENTRY *m_pEnt; CDeap<ENTRY, const ENTRY&> m_Heap; public: CHuffman(const int *data, int count): m_Heap(count), m_nCount(count) { int i; m_pEnt=new ENTRY[count*2]; for(i=0;i<count;i++) { m_pEnt[i]=ENTRY(NOPARENT, data[i]); m_Heap.Add(ENTRY(i, data[i])); } } ~CHuffman() { delete []m_pEnt; } void Solve(); //result retrieve int GetCode(int n, char *cod=NULL) const; }; //허프만 나무를 n log n 시간만에 구성한다. 힙 덕분에 가능한 복잡도임 void CHuffman::Solve() { int lp=m_nCount; ENTRY a,b; //가장 작은 놈 둘을 빼낸다. while(m_Heap.GetCount()>=2) { a=m_Heap.GetMin(); m_Heap.RemoveMin(); b=m_Heap.GetMin(); m_Heap.RemoveMin(); m_pEnt[a.index].index=-lp; //left (0) side m_pEnt[b.index].index=lp; //right (1) side m_pEnt[lp]=ENTRY(NOPARENT, a.value+b.value); m_Heap.Add(ENTRY(lp, a.value+b.value)); lp++; } }
  • 12. //actual binary code, plus its length as the return value int CHuffman::GetCode(int n, char *cod) const { int j; char *cod2=cod; for(j=0;m_pEnt[n].index!=NOPARENT;j++) { if(cod) { *cod='0'+(m_pEnt[n].index>0); cod++; } n=abs(m_pEnt[n].index); } if(cod) { *cod=0; _strrev(cod2); } //reverse the order. _strrev는 표준 함수가 아니 기 때문에 지원하지 않는 컴파일러도 있음. return j; } //Demonstrations * * * * * * * * * * * * void DeapTest() { CDeap<int, int> pk(150); unsigned seee; int i,j, bef,arr[500]; seee=time(0); srand(seee); for(i=0;i<500;i++) arr[i]=i+1; for(j=0;j<3;j++) for(i=0;i<200;i++) Swap(arr[i], arr[rand()%100]); printf("Original order: "); for(i=0;i<150;i++) printf("%d ", arr[i]); puts("n"); for(i=0;i<150;i++) pk.Add(arr[i], 0); printf("Heap form: "); pk.Display(); puts(""); printf("Min form: "); bef=-1; while(pk.GetCount()>0) { printf("%d ", pk.GetMin()); ASSERT(bef<=pk.GetMin()); bef=pk.GetMin(); pk.RemoveMin(); } puts("n"); for(i=0;i<150;i++) pk.Add(arr[i], 1); printf("Max form: "); bef=99999; while(pk.GetCount()>0) { printf("%d ", pk.GetMax()); ASSERT(bef>=pk.GetMax()); bef=pk.GetMax(); pk.RemoveMax(); } } void HuffmanTree() {
  • 13. int seq[26]={ 1532, 418, 729, 902, 2503, 359, 614, 460, 1765, 67, 530, 1317, 580, 1148, 1266, 549, 51, 1100, 2325, 1277, 840, 280, 249, 137, 850, 214}; int i, sum; char buf[24]; CHuffman huf(seq, 26); huf.Solve(); for(i=sum=0;i<26;i++) { printf("%c's code size is %d - ", i+'A', huf.GetCode(i, buf)); puts(buf); sum+=huf.GetCode(i)*seq[i]; } printf("Compression size %dn", sum); for(i=sum=0;i<26;i++) sum+=seq[i]*5; printf("UnCompression size %dn", sum); } int main() { puts("Sorting with Deap:"); DeapTest(); puts("nnHuffman tree:"); HuffmanTree(); return 0; } 5)-2 #include<stdio.h> #include<stdlib.h> struct sort { char c; double d; }; //문자와 확률을 넘겨 받는 구초제형 선언 #define MAX_ELEMENT 100
  • 14. typedef struct TreeNode{ int weight; struct TreeNode *left_child; struct TreeNode *right_child; }TreeNode; typedef struct element{ TreeNode *ptree; int key; }element; typedef struct HeapType{ element heap[MAX_ELEMENT]; int heap_size; }HeapType; void print(TreeNode *root); void init(HeapType *h) { h->heap_size=0; } //삽입함수
  • 15. void insert_min_heap(HeapType *h, element item) { int i; i = ++(h->heap_size); //트리를거슬러올라가면서부모노드와비교하는과정그래야인덱스를찾지 while((i != 1) && (item.key < h->heap[i/2].key)){ h->heap[i] = h->heap[i/2]; i /= 2; } h->heap[i] = item; //새로운노드삽입 } //삭제함수 element delete_min_heap(HeapType *h) { int parent, child; element item, temp;
  • 16. item = h->heap[1]; temp = h->heap[(h->heap_size)--]; parent = 1; child = 2; while(child <= h->heap_size){ //현재노드의자식노드중더작은자식노드를찾는다. if((child< h->heap_size) && (h->heap[child].key > h->heap[child+1].key)) child++; if(temp.key <= h->heap[child].key) break; //한단계아래로이동 h->heap[parent] = h->heap[child]; parent = child; child *= 2; } h->heap[parent] = temp; return item; }
  • 17. //이진트리생성함수 TreeNode *make_tree(TreeNode *left, TreeNode *right) { TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode)); if(node == NULL){ fprintf(stderr,"메모리할당에러n"); exit(1); } node->left_child = left; node->right_child = right; return node; } //이진트리제거함수 void destroy_tree(TreeNode *root) { if(root == NULL) return; destroy_tree(root->left_child); destroy_tree(root->right_child);
  • 18. free(root); } //허프만코드생성함수 void huffman_tree(struct sort arr[], int n) { int i; HeapType heap; element e, e1, e2; TreeNode *node, *x; //int k; init(&heap); for(i=0;i<n;i++){ node = make_tree(NULL,NULL); e.key = node->weight = arr[i]; e.ptree = node; insert_min_heap(&heap, e); } //for(i=0;i<=n;i++) // printf("%d->",heap.heap[i].key);
  • 19. for(i=1;i<n;i++){ //최소값을가지는두개의노드를삭제 e1 = delete_min_heap(&heap); /*printf("방금힙에서꺼낸것: %dn", e1.key); for(k=1;k<n;k++) printf("꺼내고난후에힙배열: %dn",heap.heap[k].key);*/ e2 = delete_min_heap(&heap); /*printf("그다음힙에서꺼낸것: %dn", e2.key); for(k=1;k<n;k++) printf("꺼내고난후에힙배열: %dn",heap.heap[k].key);*/ //두개의노드를합친다. x = make_tree(e1.ptree, e2.ptree); e.key = x->weight = e1.key + e2.key; //printf("e.key=%d, x->weight=%dn",e.key, x->weight); e.ptree = x; insert_min_heap(&heap, e); //printf("%dn", heap.heap[4].key); }
  • 20. e = delete_min_heap(&heap); //최종트리 //print(e.ptree); //원래나오는최종트리heap배열엔: 4 6 12 15 8 destroy_tree(e.ptree); } void print(TreeNode *root) { if(root){ print(root->left_child); print(root->right_child); printf("(%d)",root->weight); } } void main() { struct sort arr[100],; //구조체형 배열을 선언하여 입력받음 int i=0,j=0,m;
  • 21. for(i=0;i<100;i++) { for(j=0;j<100;j++) { arr[i].c='0'; arr[i].d='0'; } } j=0; while(j!=6) { scanf("%c %lfn",&arr[j].c,&arr[j].d); j++; } for(i=0;i<j;i++) { printf("%c %fn",arr[i].c,arr[i].d); //printf("i=%d",i); } huffman_tree(arr, 5); }