카테고리 없음

백준 [자바 java] 20920: 영단어 암기는 괴로워

잔디🌿 2025. 6. 28. 19:42

https://www.acmicpc.net/problem/20920

단어가 주어지고, 각 조건을 만족하는 순서대로 출력을 해야한다.

처음엔 실버 3문제라 쉽게 풀릴거라고 생각했는데 생각보다 쉽지 않았다.

이 문제는 java의 유용한 라이브러리를 많이 써야하는 문제였다.

 

해설

for(int i =0;i<n;i++){
  arr[i] = br.readLine();
  if(arr[i].length()>=m) map.put(arr[i],map.getOrDefault(arr[i],0)+1);
}

단어를 입력받을 때, 단어가 조건의 길이를 넘기면 해시맵에 해당 단어를 넣는다.

이때 value값은 해당 단어가 나온 횟수이다. map에 이미 단어가 존재한다면 그 value를 꺼내서 1을 더해 다시 넣어주고, 아니면 1을 넣어준다

나는 보통 이럴 때 contains 함수를 사용했는데 getOrDefault 함수를 쓰니 더 편리하다

 

List<String> list = new ArrayList<>(map.keySet());

그 다음 리스트에 map에 들어가있는 key들을 넣어준다. map.keySet()를 하면 map 내부의 key값들이 리스트로 반환된다

 

이때 중요한 점이 있다.

나는 LinkedList를 주로 사용해서 이번에도 그렇게 했는데 시간초과가 났다. ArrayList를 써야 성능이 더 좋다고 한다

앞으로는 웬만하면 ArrayList를 사용해야겠다.

아 그런데 큐는 LinkedList 사용해야한다고 한다!

 

Collections.sort(list,new Comparator<String>(){
  @Override
  public int compare(String o1,String o2){
    if(Integer.compare(map.get(o1), map.get(o2))!=0){
      return map.get(o2)-map.get(o1);
    }
    if(o1.length() != o2.length()){
      return o2.length() - o1.length();
    }
    return o1.compareTo(o2);
  }
});

그 다음 이 문제의 핵심인 comparator이다. 

이건 써도써도 헷갈린다.

Integer.compare 함수를 쓰면 같으면 0, 앞이 크면 1, 뒤가 크면 -1을 반환한다고 한다.

그리고 compareTo를 사용하면 String을 사전순으로 정렬할 수 있다. 우리는 사전순으로 오름차순으로 정렬하고자 하니까 o1.compareTo(o2)로 작성하였다.

 

StringBuilder sb = new StringBuilder();

for(int i =0 ;i<list.size();i++){
  sb.append(list.get(i)+"\n");
}

System.out.println(sb);

 

또한 결과값을 출력할 때 그냥 출력하면 시간초과가 난다.

따라서 java에서 출력을 빠르게 하도록 지원하는 StringBuilder을 사용해야한다

 

import java.io.*;
import java.util.*;
import java.math.*;

public class Main {

  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    HashMap<String, Integer> map = new HashMap<>();

    int n = Integer.parseInt(st.nextToken());
    int m = Integer.parseInt(st.nextToken());

    String[] arr = new String[n];

    for(int i =0;i<n;i++){
      arr[i] = br.readLine();
      if(arr[i].length()>=m) map.put(arr[i],map.getOrDefault(arr[i],0)+1);
    }

    List<String> list = new ArrayList<>(map.keySet());

    Collections.sort(list,new Comparator<String>(){
      @Override
      public int compare(String o1,String o2){
        if(Integer.compare(map.get(o1), map.get(o2))!=0){
          return map.get(o2)-map.get(o1);
        }
        if(o1.length() != o2.length()){
          return o2.length() - o1.length();
        }
        return o1.compareTo(o2);
      }
    });

    StringBuilder sb = new StringBuilder();

    for(int i =0 ;i<list.size();i++){
      sb.append(list.get(i)+"\n");
    }

    System.out.println(sb);


  }
}

 

전체 코드이다.

여러모로 까다롭지만 중요한 문제였다.