백준 20920 영단어 암기는 괴로워[JAVA]

Ga0·2023년 6월 8일
0

baekjoon

목록 보기
68/137
post-custom-banner

문제 해석

  • 첫번째 줄에는 영어 지문에 나오는 단어의 개수 N과 외울 단어의 길이(각각의 단어의 길이) M을 입력받는다.
  • 모두 입력을 받았다면 영단어를 N개 만큼 입력받는다.
  • 입력받은 단어의 길이가 M이상이면서,
    1. 자주 나오는 단어일 수록 앞에 배치
    1. 해당 단어의 길이가 길 수록 앞에 배치
    2. 알파벳 사전 순으로 앞에 있는 단어일수록 앞에 배치
  • 위와 같은 우선순위로 배치하여 출력한다.

코드

import java.util.*;
import java.io.*;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken()); //입력받을 영단어 수
        int M = Integer.parseInt(st.nextToken()); //출력할 단어의 길이

        String[] words = new String[N]; //영단어 저장할 배열

        for(int i = 0; i < N; i++){
            words[i] = br.readLine();
        }

        br.close();

        List<String> result = findSolution(words);

        for(int i = 0; i < result.size(); i++){
            if(result.get(i).length() < M) continue;
            bw.write(result.get(i) + "\n");
        }

        bw.flush();
        bw.close();
    }

    //조건 1~3을 처리해서 배열을 반환시키는 메소드
    static List<String> findSolution(String[] array){
        Map<String, Integer> mp = new HashMap<>();

        for (int i = 0; i < array.length ; i++) {
            //이미 Map에 있는 건 같은 값을 한번더 마주한 것
            if (mp.containsKey(array[i])) {
                // 해당 array[i]을 key 값으로 가지고, 그 key 값의 value(지금까지의 빈도수) + 1
                mp.put(array[i], mp.get(array[i]) + 1);
            } else {// 한 번도 마주한 적이 없는 숫자일 경우
                // 해당 array[i]을 key 값으로 가지고, 빈도수는 당연히 1이므로 value는 1 값을 가짐
                mp.put(array[i], 1);
            }
        }

        //키 값이 영단어인데 해당 영단어만 뽑아서 리스트로 만듬
        List<String> wordList = mp.keySet().stream().collect(Collectors.toList());

        wordList.sort((o1, o2) -> {
            int c1 = mp.get(o1); //빈도수
            int c2 = mp.get(o2); //빈도수

            if(c1 == c2){ //빈도수가 같으면 (조건1)
                if(o1.length() == o2.length()) { //단어의 길이가 같으면(조건2)
                    return o1.compareTo(o2); //3. 알파벳 사전 순으로 앞에 있는 단어일수록 앞에 배치
                }
                return o2.length()-o1.length(); //2. 해당 단어의 길이가 길 수록 앞에 배치
            }
            return c2-c1; //1. 자주 나오는 단어일 수록 앞에 배치
        });

        return wordList;
    }

}
  • 조건을 체크하는 것이 좀 어려웠다.
  • CompareTo를 사용한 적은 있는데, 너무 오랜만이라서 사용방법을 잠시 잊어 헤맸었다.
  • 코드에 대한 설명은 코드 주석으로 작성해두었다

결과

느낀점

  • 좀 많이 헤맸던 문제여서 나중에 한 번 다시 봐야할 것 같다.
post-custom-banner

2개의 댓글

comment-user-thumbnail
2024년 4월 9일

위 결과물을 출력할때
System.out.println(result.get(i));
위 방식으로 하면 시간초과가 뜨고
bw.wrtie(result.get(i) + "\n") 할 경우는 안 뜨는데
Hash Map 특성상 BufferedWrtier가 입력 받기 쉬운 구조를 띄어서 그런건가요?

1개의 답글