메뉴 건너뛰기


Computer Science > Language Processing

Korean 한글 초성 추출 프로그램

2013.11.29 00:28

푸우 조회 수:11563

앞번 게시글에 있는 "한글 초성 추출을 위한 기초 자료"를 토대로 만든 한글문자열에서 초성을 추출하는 프로그램입니다.
전에도 이야기 한 것 처럼 조합형으로 변환해서 초성을 알아내는 방법이 정석(?)이겠지만...
IF문을 통해 추출하는 것이 One Pass 처리로 빠르고 코드도 짧을 것으로 생각합니다.
다음은 Source코드로 CP949와 EUC-KR코드만 적용할 수 있습니다.
그리고 한번에 입력가능 문자는 1024바이트입니다.
혹시 버그가 있다면 꼭 쫌 알려주세요.
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static unsigned char *getchosung(unsigned char *str)
{
  unsigned long i=0, j=0, len;
  unsigned char *cho;

  len = strlen(str);
  cho=malloc(len+1);
  for(i=0; i<len; i++) {
    if(str[i]>=0x80) {
      switch (str[i]) {
      case 0x81:  case 0x82:
        strcpy(cho+j, "ㄱ");
        break;
      case 0x83:
        if(str[i+1]<=0x89) strcpy(cho+j, "ㄱ");
        else if(str[i+1]>=0x8A) strcpy(cho+j, "ㄲ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x84:
        strcpy(cho+j, "ㄲ");
        break;
      case 0x85:
        if(str[i+1]<=0xF9) strcpy(cho+j, "ㄲ");
        else if(str[i+1]>=0xFA) strcpy(cho+j, "ㄴ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x86:  case 0x87:
        strcpy(cho+j, "ㄴ");
        break;
      case 0x88:
        if(str[i+1]<=0xA2) strcpy(cho+j, "ㄴ");
        else if(str[i+1]>=0xA3) strcpy(cho+j, "ㄷ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x89:  case 0x8A:
        strcpy(cho+j, "ㄷ");
        break;
      case 0x8B:
        if(str[i+1]<=0x4C) strcpy(cho+j, "ㄷ");
        else if(str[i+1]>=0x4D) strcpy(cho+j, "ㄸ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x8C:
        strcpy(cho+j, "ㄸ");
        break;
      case 0x8D:
        if(str[i+1]<=0xEA) strcpy(cho+j, "ㄸ");
        else if(str[i+1]>=0xEB) strcpy(cho+j, "ㄹ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x8E:  case 0x8F:
        strcpy(cho+j, "ㄹ");
        break;
      case 0x90:
        if(str[i+1]<=0xA1) strcpy(cho+j, "ㄹ");
        else if(str[i+1]>=0xA2) strcpy(cho+j, "ㅁ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x91:  case 0x92:
        strcpy(cho+j, "ㅁ");
        break;
      case 0x93:
        if(str[i+1]<=0x4A) strcpy(cho+j, "ㅁ");
        else if(str[i+1]>=0x4B) strcpy(cho+j, "ㅂ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x94:
        strcpy(cho+j, "ㅂ");
        break;
      case 0x95:
        if(str[i+1]<=0xBD) strcpy(cho+j, "ㅂ");
        else if(str[i+1]>=0xBE) strcpy(cho+j, "ㅃ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x96:  case 0x97:
        strcpy(cho+j, "ㅃ");
        break;
      case 0x98:
        if(str[i+1]<=0xAA) strcpy(cho+j, "ㅃ");
        else if(str[i+1]>=0xAB) strcpy(cho+j, "ㅅ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x99:
        strcpy(cho+j, "ㅅ");
        break;
      case 0x9A:
        if(str[i+1]<=0xEF) strcpy(cho+j, "ㅅ");
        else if(str[i+1]>=0xF0) strcpy(cho+j, "ㅆ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x9B:  case 0x9C:
        strcpy(cho+j, "ㅅ");
        break;
      case 0x9D:
        if(str[i+1]<=0xCF) strcpy(cho+j, "ㅆ");
        else if(str[i+1]>=0xD0) strcpy(cho+j, "ㅇ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0x9E:
        strcpy(cho+j, "ㅇ");
        break;
      case 0x9F:
        if(str[i+1]<=0xE7) strcpy(cho+j, "ㅇ");
        else if(str[i+1]>=0xE8) strcpy(cho+j, "ㅈ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0xA0:
        strcpy(cho+j, "ㅈ");
        break;
      case 0xA1:  case 0xA2:  case 0xA3:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅈ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0xA4:  case 0xA5:  case 0xA6:  case 0xA7:  case 0xA8:  case 0xA9:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅉ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0xAA:
        if(str[i+1]<=0x42) strcpy(cho+j, "ㅉ");
        else if(str[i+1]<=0xA0 ) strcpy(cho+j, "ㅊ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0xAB:  case 0xAC:  case 0xAD:  case 0xAE:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅊ");
        else strncpy(cho+j, str+i, 2);
        break;
      case 0xAF:
        if(str[i+1]<=0x86) strcpy(cho+j, "ㅊ");
        else strcpy(cho+j, "ㅋ");
        break;
      case 0xB0:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅋ");
        else strcpy(cho+j, "ㄱ");
        break;
      case 0xB1:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅋ");
        else if(str[i+1]<=0xED) strcpy(cho+j, "ㄱ");
        else strcpy(cho+j, "ㄲ");
        break;
      case 0xB2:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅋ");
        else strcpy(cho+j, "ㄲ");
        break;
      case 0xB3:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅋ");
        else if(str[i+1]<=0xA9) strcpy(cho+j, "ㄲ");
        else strcpy(cho+j, "ㄴ");
        break;
      case 0xB4:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅋ");
        else if(str[i+1]<=0xD8) strcpy(cho+j, "ㄴ");
        else strcpy(cho+j, "ㄷ");
        break;
      case 0xB5:
        if(str[i+1]<=0x69) strcpy(cho+j, "ㅋ");
        else if(str[i+1]<=0xA0 ) strcpy(cho+j, "ㅌ");
        else if(str[i+1]<=0xFA) strcpy(cho+j, "ㄷ");
        else strcpy(cho+j, "ㄸ");
        break;
      case 0xB6:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅌ");
        else if(str[i+1]<=0xF2) strcpy(cho+j, "ㄸ");
        else strcpy(cho+j, "ㄹ");
        break;
      case 0xB7:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅌ");
        else strcpy(cho+j, "ㄹ");
        break;
      case 0xB8:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅌ");
        else if(str[i+1]<=0xB5) strcpy(cho+j, "ㄹ");
        else strcpy(cho+j, "ㅁ");
        break;
      case 0xB9:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅌ");
        else if(str[i+1]>=0xA1 && str[i+1]<=0xD8) strcpy(cho+j, "ㅁ");
        else strcpy(cho+j, "ㅂ");
        break;
      case 0xBA:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅌ");
        else if(str[i+1]<=0xFB) strcpy(cho+j, "ㅂ");
        else strcpy(cho+j, "ㅃ");
        break;
      case 0xBB:
        if(str[i+1]<=0x4D) strcpy(cho+j, "ㅌ");
        else if(str[i+1]<=0xA0 ) strcpy(cho+j, "ㅍ");
        else if(str[i+1]<=0xE6 ) strcpy(cho+j, "ㅃ");
        else strcpy(cho+j, "ㅅ");
        break;
      case 0xBC:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅍ");
        else strcpy(cho+j, "ㅅ");
        break;
      case 0xBD:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅍ");
        else if(str[i+1]<=0xCD ) strcpy(cho+j, "ㅅ");
        else strcpy(cho+j, "ㅆ");
        break;
      case 0xBE:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅍ");
        else if(str[i+1]<=0xC5 ) strcpy(cho+j, "ㅆ");
        else strcpy(cho+j, "ㅇ");
        break;
      case 0xBF:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅍ");
        else strcpy(cho+j, "ㅇ");
        break;
      case 0xC0:
        if(str[i+1]<=0x98) strcpy(cho+j, "ㅍ");
        else if(str[i+1]<=0xA0 ) strcpy(cho+j, "ㅎ");
        else if(str[i+1]<=0xD9 ) strcpy(cho+j, "ㅇ");
        else strcpy(cho+j, "ㅈ");
        break;
      case 0xC1:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅎ");
        else strcpy(cho+j, "ㅈ");
        break;
      case 0xC2:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅎ");
        else if(str[i+1]<=0xA4 ) strcpy(cho+j, "ㅈ");
        else if(str[i+1]<=0xF6) strcpy(cho+j, "ㅉ");
        else strcpy(cho+j, "ㅊ");
        break;
      case 0xC3:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅎ");
        else strcpy(cho+j, "ㅊ");
        break;
      case 0xC4:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅎ");
        else if(str[i+1]<=0xAA) strcpy(cho+j, "ㅊ");
        else strcpy(cho+j, "ㅋ");
        break;
      case 0xC5:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅎ");
        else if(str[i+1]<=0xB7) strcpy(cho+j, "ㅋ");
        else strcpy(cho+j, "ㅌ");
        break;
      case 0xC6:
        if(str[i+1]<=0xA0) strcpy(cho+j, "ㅎ");
        else if(str[i+1]<=0xC3) strcpy(cho+j, "ㅌ");
        else strcpy(cho+j, "ㅍ");
        break;
      case 0xC7:
        if(str[i+1]<=0xCE) strcpy(cho+j, "ㅍ");
        else strcpy(cho+j, "ㅎ");
        break;
      case 0xC8:
        strcpy(cho+j, "ㅎ");
        break;
      default:
        cho[j] = str[i];
        cho[j+1= str[i+1];
        break;
      }
      j+=2;
      i++;
    } else {
      cho[j++]=str[i];
    }
  }
  cho[j]=0x00;

  return cho;
}

int main(int argc, char *argv[])
{
  unsigned char buf[1024], *cho;
  unsigned long len;

  while(1) {
    printf("> ");
    fgets(buf, 1024, stdin);
    len = strlen(buf);
    if(buf[len-1]=='\r' || buf[len-1]=='\n') buf[len-1]=0x00;
    if(buf[len-2]=='\r' || buf[len-2]=='\n') buf[len-2]=0x00;
    if(!stricmp(buf, "exit")) break;
    cho = getchosung(buf);
    printf("  %s\n", cho);
    free(cho);
  }

  return 0;
}

 
 
 
 
Creative Commons License
Creative Commons License이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Copyright 조희창(Nicholas Jo). Some rights reserved. http://bbs.nicklib.com