Java - 한글, 초성 검색

Posted 04 21, 2013 14:41, Filed under: Language/JAVA

# 검색 조건

1) 초성검색어는 최소 두 자리 이상 입력
2) 결과는 매출이 가장 많은 순서(도서가격 * 판매건수)로 내림차순
3) 초성 이외(영문,한글)의 문자는 검색에서 제외

public class HangulChosungSearch {
    private static final char INITIAL_SOUND_BEGIN_UNICODE = 12593; // 초성 유니코드 시작 값
    private static final char INITIAL_SOUND_LAST_UNICODE = 12622;  // 초성 유니코드 마지막 값
    private static final char HANGUL_BEGIN_UNICODE = 44032;        // 한글 유니코드 시작 값
    private static final char HANGUL_LAST_UNICODE = 55203;         // 한글 유니코드 마지막 값
    private static final char NUMBER_BEGIN_UNICODE = 48;           // 숫자 유니코드 시작 값
    private static final char NUMBER_LAST_UNICODE = 57;            // 숫자 유니코드 마지막 값
    private static final char ENGLISH_ROWER_BEGIN_UNICODE = 65;    // 영문(소문자) 유니코드 시작 값 
    private static final char ENGLISH_ROWER_LAST_UNICODE = 90;     // 영문(소문자) 유니코드 마지막 값
    private static final char ENGLISH_UPPER_BEGIN_UNICODE = 97;    // 영문(대문자) 유니코드 시작 값
    private static final char ENGLISH_UPPER_LAST_UNICODE = 122;    // 영문(대문자) 유니코드 마지막 값
    private static final char HANGUL_BASE_UNIT = 588;              // 자음 마다 가지는 글자수
                                                                   // 초성
    private static final char[] INITIAL_SOUND = 
        {'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ'
       , 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'};

    // 초성 검색에 대한 상품 리스트 
    public static final String[][] ITEM_ARRAY = new String[][]{
      //  상품번호 , 도서명 , 도서가격 , 판매건수
         {"8798725", "샐러드를 좋아하는 사자, 사슴?", "11700", "5"}
       , {"8787608", "아날로그 사랑법", "12600", "32"}
       , {"8809046", "엄마가 있어줄게", "12420", "72"}
       , {"8762353", "하고 싶다, 연애", "12600", "12"}
       , {"8822780", "버스 타고 제주여행 제주 구석구석 즐기는 법", "12600", "5"}
       , {"8824942", "대한민국 사진여행지 100", "15120", "21"}
       , {"8885635", "베스트 오브 유럽  230", "11900", "22"}
       , {"8930742", "지면서 이기는 관계술", "13500", "6"}
       , {"8885924", "공부와 열정", "11700", "9"}
       , {"7845549", "소셜 웹 마이닝", "21600", "121"}
       , {"243767", "학문의 즐거움", "7120", "851"}
       };
    
    /**
     * 입력받은 문자가 초성인지 체크
     */
    private static boolean isInitialSound(char c){
        for(int i=0; i<INITIAL_SOUND.length; i++){ 
            if(INITIAL_SOUND[i] == c){ 
                return true; 
            } 
        } 
        return false; 
    } 

    /**
     * 입력받은 문자의 자음을 추출
     */
    private static char getInitialSound(char c){ 
        int hanBegin = (c - HANGUL_BEGIN_UNICODE); 
        int index = hanBegin / HANGUL_BASE_UNIT; 
        return INITIAL_SOUND[index]; 
    } 
    
    /**
     * 입력받은 문자가 한글인지 체크
     */
    private static boolean isHangul(char c){ 
        return HANGUL_BEGIN_UNICODE <= c && c <= HANGUL_LAST_UNICODE; 
    }
    
    /**
    * 숫자, 영문(대소문자), 한글, 초성 등의 유니코드를 체크
    */
    private static boolean checkUnicode(char c){
        if ((   (c >= NUMBER_BEGIN_UNICODE && c <= NUMBER_LAST_UNICODE) 
             || (c >= ENGLISH_UPPER_BEGIN_UNICODE && c <= ENGLISH_UPPER_LAST_UNICODE) 
             || (c >= ENGLISH_ROWER_BEGIN_UNICODE && c <= ENGLISH_ROWER_LAST_UNICODE) 
             || (c >= HANGUL_BEGIN_UNICODE && c <= HANGUL_LAST_UNICODE) 
             || (c >= INITIAL_SOUND_BEGIN_UNICODE && c <= INITIAL_SOUND_LAST_UNICODE))
           ){
            return true;
        }else{
            return false;
        }
    }

    /**
    * 검색어와 검색 대상 값을 입력받아서 일치여부 확인
    */
    public static boolean matchString(String keyword, String value){ 
        int t = 0; 
        int seof = value.length() - keyword.length(); 
        int slen = keyword.length();
        // 검색어가 검색대상값보다 더 길거나, 검색어가 두개 이하일때 false 리턴 
        if(seof < 0 || keyword.length() < 2){
            return false;
        }
        
        for(int i = 0;i <= seof;i++){ 
            t = 0; 
            while(t < slen){ 
                // 숫자, 초성, 한글, 영문(대소문자)를 제외한 다른 값은 false 리턴 
                if(!checkUnicode(keyword.charAt(t))){
                    return false;
                }
                
                // 검색어가 초성이이고 한글이면 초성끼리 비교
                if(isInitialSound(keyword.charAt(t)) && isHangul(value.charAt(i+t))){ 
                    // 각각의 초성이 같은지 비교 
                    if(getInitialSound(value.charAt(i+t)) == keyword.charAt(t)){ 
                        t++; 
                    }else{ 
                        break;
                    }
                } else { 
                    // 초성이 아닐경우 비교 
                    if(value.charAt(i+t) == keyword.charAt(t)){
                        t++; 
                    }else{ 
                        break;
                    }
                } 
            } 
            // 검색어의 길이만큼 모두 일치하면 true를 리턴 
            if(t == slen){
                return true;
            }
        } 
        return false; // 일치하지 않으면 false를 리턴
    }
    
    /**
    * 상품명 검색및 매출액에 따른 정렬
    */
    public static void searchItem(String keyword){
        String[] itemTitle = new String[20]; // 상품명을 담을 변수
        int[] machool = new int[20];         // 매출금액을 담을 변수
        
        // 총 상품의 건수만큼 for 문을 수행 
        for(int i=0; i<ITEM_ARRAY.length; i++){
            // 키워드와 매칭되는 상품이 존재하면, 상품명과 매출액을 배열에 각각 저장 
            if(matchString(keyword, ITEM_ARRAY[i][1])){
                itemTitle[i] = ITEM_ARRAY[i][1];
                machool[i] = Integer.parseInt(ITEM_ARRAY[i][2])*Integer.parseInt(ITEM_ARRAY[i][3]);
            }
        }
        
        // 매출액이 큰 순서부터 내림차순 정렬 
        for (int i = 0; i < machool.length; i++){
            boolean changed = false;

            for (int j = i + 1; j < machool.length; j++){
                if (machool[j] > machool[i]){
                    // 매출액의 순서를 정렬 
                    int tempMachool = machool[j];
                    machool[j] = machool[i];
                    machool[i] = tempMachool;
                    // 상품명의 순서를 정렬
                    String tempItemTitle = itemTitle[j];
                    itemTitle[j] = itemTitle[i];
                    itemTitle[i] = tempItemTitle;
                    changed = true;
                }
            } // 정렬 for문 종료
            if (!changed){ // 더이상 순서 변경이 없으면 for문을 빠져 나옴
                break;
            }
            System.out.println("도서명 :"+itemTitle[i]+", 매출액 :"+machool[i]);
        } // 전체 for문 종료
    }

    // 메인 메서드 
    public static void main(String[] arr){
        // 검색할 초성 입력
        searchItem("ㅈㄱ");
    }
}
/*
### 출력 결과 ###
도서명 :학문의 즐거움, 매출액 :6059120
도서명 :엄마가 있어줄게, 매출액 :894240
도서명 :버스 타고 제주여행 제주 구석구석 즐기는 법, 매출액 :63000
*/

※ 위 내용은, 여러 자료를 참고하거나 제가 주관적으로 정리한 것입니다.
   잘못된 정보나 보완이 필요한 부분을, 댓글 또는 메일로 보내주시면 많은 도움이 되겠습니다.
04 21, 2013 14:41 04 21, 2013 14:41


Trackback URL : http://develop.sunshiny.co.kr/trackback/911

Leave a comment


Recent Posts

  1. HDFS - Python Encoding 오류 처리
  2. HP - Vertica ROS Container 관련 오류...
  3. HDFS - Hive 실행시 System Time 오류
  4. HP - Vertica 사용자 쿼리 이력 테이블...
  5. Client에서 HDFS 환경의 데이터 처리시...

Recent Comments

  1. I'm curious to find out what blog... 레깅스룸 03시 26분
  2. 안녕하세요^^ 배그핵
  3. 안녕하세요^^ 도움이 되셨다니, 저... sunshiny
  4. 정말 큰 도움이 되었습니다.. 감사합... 사랑은
  5. 네, 안녕하세요. 댓글 남겨 주셔서... sunshiny

Recent Trackbacks

  1. wedding dj’s in bozeman montana wedding dj’s in bozeman montana %M
  2. important site important site %M
  3. host insurance host insurance %M
  4. why not try here why not try here %M
  5. airbnb homeowners insurance airbnb homeowners insurance %M

Calendar

«   01 2020   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Bookmarks

  1. 위키피디아
  2. MysqlKorea
  3. 오라클 클럽
  4. API - Java
  5. Apache Hadoop API
  6. Apache Software Foundation
  7. HDFS 생태계 솔루션
  8. DNSBL - Spam Database Lookup
  9. Ready System
  10. Solaris Freeware
  11. Linux-Site
  12. 윈디하나의 솔라나라

Site Stats

TOTAL 2825798 HIT
TODAY 266 HIT
YESTERDAY 1151 HIT