CodeWars 일백 여섯 번째 문제

Updated:

Most frequently used words in a text

public static List<String> top3(String s) {
    	
    PriorityQueue<HashMap.Entry<String, Integer>> pQueue 
        = new PriorityQueue<HashMap.Entry<String,Integer>>
        ((a,b) -> a.getValue()==b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue()-a.getValue());

    HashMap<String, Integer> wordMap = new HashMap<String, Integer>();

    s = s.replaceAll("[^ 'a-zA-Z]", " ").trim().replaceAll(" +", " ").replaceAll("'+", "'");

    while(s.length() > 0) {
        String[] split = s.split(" ");
        int count = countWord(split);

        s = String.join(" ", split).trim();

        if(count > 0) {
            wordMap.put(split[0], count);
        }
    }

    for(HashMap.Entry<String, Integer> entry: wordMap.entrySet())
    {
        pQueue.offer(entry);
    }

    return covertQueueToList(pQueue);
}

private static List<String> covertQueueToList(PriorityQueue<Entry<String, Integer>> pQueue) {
    List<String> list = new ArrayList<String>();

    int i = 0;

    while(!pQueue.isEmpty() && i < 3) {
        list.add(pQueue.poll().getKey().toLowerCase());
        i++;
    }

    return list;
}

public static int countWord(String[] split) {
    int count = 0;

    for(int i = 0; i < split.length; i++) {

        if("'".equals(split[0])) {
            split[i] = "";
        }

        if(split[0].equals(split[i])) {
            count++;
            split[i] = "";
        }
    }

    return count;
}
  • 문제는 크게 어렵지 않았으나 코드가 너무 더러워 졌다.
public class TopWords {

    final static private Pattern P = Pattern.compile("[a-z][a-z']*");
    
    public static List<String> top3(String s) {
        
        Map<String,Integer> cnt = new HashMap<>();
        Matcher m = P.matcher(s.toLowerCase());
        while (m.find()) {
            cnt.put(m.group(), cnt.getOrDefault(m.group(), 0)+1);
        }
        return cnt.entrySet().stream().sorted(TopWords::compare)
                  .limit(3).map(Map.Entry::getKey).collect(toList());
    }
    
    private static int compare(Map.Entry<String,Integer> a, Map.Entry<String,Integer> b) 	{
        int u = a.getValue(), v = b.getValue();
        return -Integer.compare(u,v);
    }
}

public static List<String> top3(String s) {
        String[] str = s.toLowerCase().split( "[^a-z']" );
        Map<String, Integer> map = new TreeMap<>();
        for (String ss:str             ) {
            if (ss.matches( "[a-z]+\'*[a-z]*" )) {
                if (!map.containsKey( ss )) {
                    map.put( ss, 1 );
                } else {
                    map.put( ss, map.get( ss ) + 1 );
                }
            }
        }
        List<String> lst = new ArrayList<>();
        lst = map.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .map( ss->ss.getKey() )
                .limit(3)
                .collect( Collectors.toList());

        return lst;
    }
  • Best 코드들은 굉장히 깔끔하게 짰다.
  • 정규식관련해서 아직 미숙하기 때문에 내 코드가 더러워진 것 같다.
  • 더욱이 람다식을 사용하지도 않아서 우선순위 큐와 map을 사용하느라 더 더러워 졌다.
  • 조만간 정규식과 람다식에 대해서 정리좀 해야겠다.