본문 바로가기

Java/알고리즘

[자바 알고리즘 인터뷰] 6장 문자열 처리(4) 가장 흔한 단어

https://leetcode.com/problems/most-common-word/description/

 

 

- 금지된 단어를 제외하고 가장 흔하게 등장하는 단어를 출력하라, 대소문자를 구분하지 않으며, 구두점(마침표, 쉼표 등)또한 무시한다. 

 

풀이 1) 전처리 작업 후 개수 처리 및 추출

 

- 입력값에는 대소문자가 섞여 있으며 쉼표 등 구두점이 존재한다.

- 따라서 데이터 클렌징(Data Cleansing)이라 부르는 입력값에 대한 전처리(Processing) 작업이 필요하다. 

 

- 정규식에서 \W는 단어 문자(Word Character)가 아닌 것을 뜻한다. 

- 단어 문자를 뜻할 때는 \w를 사용 

- 문자 뒤에 +를 붙이면 연속적인 값을 의미한다. 

- \W+연속적으로 단어 문자가 아닌 값을 의미

 

replaceAll("\\W+"," ")

- 연속적으로 단어 문자가 아닌 값을 모두 공백으로 치환하라는 명령어 

 

-이 외에 제약 조건으로 대소문자를 구분하지 않으므로 toLowerCase()로 모두 소문자로 바꿔주며, split(" ")을 써서 띄어쓰기를 기준으로 단어를 모두 분리한다. 

 

 String[] words = paragraph.replaceAll("\\W+", " ").toLowerCase().split(" ");

 

 

- 금지된 단어를 제외하고 각 단어가 몇 차례나 등장하는지 개수를 헤아림

- getOrDefault() 메소드는 값이 존재하지 않는 경우 기본값을 출력하며 존재하는 경우에는 해당되는 값을 출력한다. 여기에 +1을 하고 다시 저장한다. 

- 반복문을 모두 돌고 나면 각 단어별 개수가 counts에 저장될 것이다.

 

for(String w: words) {
            //금지된 단어가 아닌 경우 개수 처리
            if(!ban.contains(w)){
                //존재하지 않는 단어라면 기본값을 0으로 지정. 추출한 값에 +1 하여 저장
                counts.put(w, counts.getOrDefault(w,0)+1);
            }
        }

 

 

- 가장 흔하게 등장하는 단어 찾기 

 

- Collections.max()는 가장 큰 값을 찾는다.

- counts.entrySet()에서 가장 큰 값을 찾으며, 찾는 기준은 map.Entry.comparingByValue()이며 값을 기준으로 비교한다는 의미이다. 

- getKey()는 최종적으로 키만 가져오게 된다. 

 

//가장 흔하게 등장하는 단어 추출
return Collections.max(counts.entrySet(), Map.Entry.comparingByValue()).getKey();

 

 

import java.util.*;

class Solution {
    public String mostCommonWord(String paragraph, String[] banned) {
        //금지어 목록이 String 배열이므로, 비교 메소드를 제공하는 Set으로 변경
        Set<String> ban = new HashSet<>(Arrays.asList(banned));

        //각 단어별 개수가 저장될 키-값 맵
        Map<String,Integer> counts = new HashMap<>();

        //전처리 작업 후 단어 목록을 배열로 저장
        String[] words = paragraph.replaceAll("\\W+", " ").toLowerCase().split(" ");

        for(String w: words) {
            //금지된 단어가 아닌 경우 개수 처리
            if(!ban.contains(w)){
                //존재하지 않는 단어라면 기본값을 0으로 지정. 추출한 값에 +1 하여 저장
                counts.put(w, counts.getOrDefault(w,0)+1);
            }
        }

        //가장 흔하게 등장하는 단어 추출
        return Collections.max(counts.entrySet(), Map.Entry.comparingByValue()).getKey();

        
    }
}

 

실행시간: 18밀리초