'한글자동변환'에 해당되는 글 1

  1. 2011.09.16 java] 영문입력 -> 한글입력 으로 변환
IT_Expert/Java & Jsp | Posted by 낫기법필 2011. 9. 16. 09:21

java] 영문입력 -> 한글입력 으로 변환


[ 쥔장 ]=================================
현재는 쓸일이 아직은 없지만 나중에 활용하면 유용할 것 같아 스크랩함.
지식인을 통해 얻음.
===================================


[질문]----------------------------------

자바로 프로그램을 작성하려고 하는데... 만들려는 프로그램은 
한/영 키를 영어로 해 놓고 한글 입력을 하면 
예를 들어 입력을 
"zjavbxj tkTek "  
이렇게 하면 
자바에서 이걸 읽어들여서 
"컴퓨터 샀다" 
 이렇게 바꾸려고 하는데... 
 
제가 한건.. 그저.. 
알파벳 하나씩 끊어서 
"ㅋㅓㅁㅍㅠㅌㅓ ㅅㅏㅆㄷㅏ" 
 이렇게 밖에 못하겠어요,,,  

고수님들 도와주세요~~   

"컴퓨터 샀다" 
이렇게 하려면 어떻게 해야 하나요???


----------------------------------------


[답변]----------------------------------

이 질문을 보고 저는 첨에 한글 자모음을 모두 맵(map)으로 만들어서 쓰는 방법을
생각했는데... 불가능은 아니지만 말 그대로 엄청난 생노가다를 필요로 하는 일이라
관뒀습니다. 그런데 찾아보니 자바스크립트 버젼으로 영한 오토마타가 있기에 자바
버젼으로 바꾸었습니다. 

자바스크립트 자체가 자바 문법과 비슷한 관계로 소스의 핵심부분은 거의 손대지
않아도 되었구요. 다만, 그대로 쓰기에는 StringIndexOutOfBoundExcption이 나는 관계로
모두 메서드로 분리해서 체크하도록 만들었습니다. 

※ 소스 원작자께 연락을 하고싶었는데, 어디로 해야할지 찾을 수가 없었기 때문에
      부득이하게 불펌(?)에 무단개작(?)을 하게되었습니다. 하지만 어디까지나 지식공유를
      위한 목적이므로 양해해주시기 바랍니다.

 ※ 자바 영한 오토마타를 구하시는 분들께 조금이나마 도움이 되었으면 합니다 ^-^a

 ※ 원소스 : 자바스크립트 버젼 영한오토마타 / ROKAF CC 568th 김건호
     개    작 : 자바 컨버젼 / 박영민 06. 8. 1

 소스코드 ---------------------------------------------------------------------------------

 

package test;

import java.io.UnsupportedEncodingException;

public class TempTest {
 // 코드타입 - 초성, 중성, 종성
 enum CodeType{chosung, jungsung, jongsung}
 
 public static void main(String[] args) throws UnsupportedEncodingException {
  TempTest ts1 = new TempTest();
  String result = ts1.engToKor("zjavbxjtkTek");
  System.out.println(result);
 }
 
 /**
   * 영어를 한글로...
   */
 public String engToKor(String eng){
  StringBuffer sb = new StringBuffer();
  int initialCode = 0, medialCode = 0, finalCode = 0;
  int tempMedialCode, tempFinalCode;
  
  for(int i = 0; i < eng.length(); i++){
   // 초성코드 추출
   initialCode = getCode(CodeType.chosung, eng.substring(i, i+1));   
   i++; // 다음문자로
   
   // 중성코드 추출
   tempMedialCode = getDoubleMedial(i, eng);   // 두 자로 이루어진 중성코드 추출
   
   if(tempMedialCode != -1){       
    medialCode = tempMedialCode;
    i += 2;
   }else{            // 없다면,
    medialCode = getSingleMedial(i, eng);   // 한 자로 이루어진 중성코드 추출
    i++;
   }
   
   // 종성코드 추출
   tempFinalCode = getDoubleFinal(i, eng);    // 두 자로 이루어진 종성코드 추출    
   if(tempFinalCode != -1){
    finalCode = tempFinalCode;
    // 그 다음의 중성 문자에 대한 코드를 추출한다.
    tempMedialCode = getSingleMedial(i+2, eng);
    if( tempMedialCode != -1 ){      // 코드 값이 있을 경우
     finalCode = getSingleFinal(i, eng);   // 종성 코드 값을 저장한다.
             }else{
              i++;
             }
   }else{            // 코드 값이 없을 경우 ,
    tempMedialCode = getSingleMedial(i+1, eng);  // 그 다음의 중성 문자에 대한 코드 추출. 
    if(tempMedialCode != -1){      // 그 다음에 중성 문자가 존재할 경우,     
     finalCode = 0;        // 종성 문자는 없음.
     i--;     
    }else{
     finalCode = getSingleFinal(i, eng);   // 종성 문자 추출
     if( finalCode == -1 )
      finalCode = 0;
    }
   }
   // 추출한 초성 문자 코드, 중성 문자 코드, 종성 문자 코드를 합한 후 변환하여 스트링버퍼에 넘김
   sb.append((char)(0xAC00 + initialCode + medialCode + finalCode));
  }  
  return sb.toString();
 }
 
 /**
   * 해당 문자에 따른 코드를 추출한다.
   * @param type 초성 : chosung, 중성 : jungsung, 종성 : jongsung 구분
   * @param char 해당 문자
   */
 private int getCode(CodeType type, String c){
  // 초성
  String init = "rRseEfaqQtTdwWczxvg";
  // 중성
  String[] mid = {"k","o","i","O","j","p","u","P","h","hk", "ho","hl","y","n","nj","np", "nl", "b", "m", "ml", "l"};
  // 종성
  String[] fin = {"r", "R", "rt", "s", "sw", "sg", "e", "f", "fr", "fa", "fq", "ft", "fx", "fv", "fg", "a", "q", "qt", "t", "T", "d", "w", "c", "z", "x", "v", "g"};
  
  switch(type){
   case chosung :
    int index = init.indexOf(c);
    if( index != -1 ){
     return index * 21 * 28;
    }
    break;
   case jungsung :
    
    for(int i = 0; i < mid.length; i++){
     if(mid[i].equals(c)){
       return i * 28;
      }
    }
    break;
   case jongsung :
    for(int i = 0; i < fin.length; i++){
     if(fin[i].equals(c)){
       return i + 1;
      }
    }
    break;
   default:
    System.out.println("잘못된 타입 입니다");
  }
  
  return -1;
 }
 
 // 한 자로 된 중성값을 리턴한다
 // 인덱스를 벗어낫다면 -1을 리턴
 private int getSingleMedial(int i, String eng){
  if((i+1) <= eng.length()){
   return getCode(CodeType.jungsung, eng.substring(i, i+1));
  }else{
   return -1;
  }
 }
 
 // 두 자로 된 중성을 체크하고, 있다면 값을 리턴한다.
 // 없으면 리턴값은 -1
 private int getDoubleMedial(int i, String eng){
  int result;
  if((i+2) > eng.length()){
   return -1;
  }else{
   result = getCode(CodeType.jungsung, eng.substring(i, i+2));
   if(result != -1){
    return result;
   }else{
    return -1;
   }
  }
 }
 
 // 한 자로된 종성값을 리턴한다
 // 인덱스를 벗어낫다면 -1을 리턴
 private int getSingleFinal(int i, String eng){
  if((i+1) <= eng.length()){
   return getCode(CodeType.jongsung, eng.substring(i, i+1));
  }else{
   return -1;
  }
 }
 
 // 두 자로된 종성을 체크하고, 있다면 값을 리턴한다.
 // 없으면 리턴값은 -1
 private int getDoubleFinal(int i, String eng){
  if((i+2) > eng.length()){
   return -1;
  }else{
   return getCode(CodeType.jongsung, eng.substring(i, i+2));
  }
 }
}

----------------------------------------------------------------------------------------------------


----------------------------------------


[ 출처 : http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040201&docId=65942779&qb=amF2YSDtgqQg7J6F66Cl&enc=utf8&section=kin&rank=3&search_sort=0&spq=0&pid=gDVNMc5Y7t0ssaAZMXKssc--121073&sid=TlsStnYEW04AADDgIHI ]