[백준] 20920번 : 영단어 암기는 괴로워 (실버 Ⅲ) - Java/자바

2025. 7. 3.·Problem Solving (Java)/백준
반응형


✅ 문제

문제링크

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

 


✅ 풀이

🔹 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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());
        StringBuilder sb = new StringBuilder();
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        Map<String, Integer> map = new HashMap<>();
        while (n-- > 0) {
            String word = br.readLine();
            if (word.length() >= m) {
                map.put(word, map.getOrDefault(word, 0) + 1);
            }
        }
        List<String> list = new ArrayList<>(map.keySet());
        Collections.sort(list, (w1, w2) -> {
            if (map.get(w1) == map.get(w2)) {
                if (w1.length() == w2.length()) {
                    return w1.compareTo(w2); // 3. 사전 순으로 앞에 있는 단어를 앞에 배치
                } else {
                    return w2.length() - w1.length(); // 2. 길이가 길수록 앞에 배치
                }
            } else {
                return map.get(w2) - map.get(w1); // 1. 자주 나올 수록 앞에 배치
            }
        } );
        
        // 우선순위 정렬 조건을 조금 더 간결하게 한 코드
        /*list.sort((w1, w2) -> {
            if (map.get(w1) != map.get(w2)) {
                return map.get(w2) - map.get(w1);
            }
            if (w1.length() != w2.length()) {
                return w2.length() - w1.length();
            }
            return w1.compareTo(w2);
        });*/
		
        // foreach문을 통해 ArrayList의 요소를 쉽게 꺼낼 수 있다.
        for (String str : list) {
            sb.append(str).append("\n");
        }
        sb.setLength(sb.length() - 1);
        System.out.println(sb);
    }
}

 

이 문제는 n개의 영단어를 입력받아 단어장을 만드는데 중복은 제거하고 길이가 m이상인 단어들을 다음 우선순위에 맞게 앞에 적는다.

    • 1. 자주 나오는 단어일수록 앞에 배치한다.
    • 2. 해당 단어의 길이가 길수록 앞에 배치한다.
    • 3. 알파벳 사전 순으로 앞에 있는 단어일수록 앞에 배치한다.

자주 나오는 단어인지 확인해야하므로 HashMap을 사용해 key에는 단어를 저장하고 value에는 나온 횟수를 저장하도록 하자.

StringTokenizer st를 선언해 n과 m을 입력받고 저장하도록 한다.

 

Map<String, Integer> map = new HashMap<>();하여 map을 선언해주도록 한다.

while문에 조건을 n-- >0하여 n번 반복하도록 한다.

String word에 단어를 입력받아 저장하고 if문에 조건을 word.length() >= m하여 m이상인 단어인지 확인한다.

단어의 길이가 m이상이라면 map.put(word, map.getOrDefault(word, 0) + 1);하여 key에는 word를 저장하고 value값에는 getOrDefault()메서드를 사용해 key값이 있으면 해당 키의 value값을 반환하고 key가 없다면 value값으로 0을 반환하도록 한다.

반환값에 + 1해주어 세어준다.

 

반복이 종료되면 HashMap은 순서가 보장되지 않으므로 List<String> list = new ArrayList<>(map.keySet());하여 HashMap의 key들을 ArrayList에 넣어도록 한다.

Collections.sort(list, (w1, w2) -> {});하여 list를 정렬하고 두번째 인자로 Comparator을 람다식을 사용해 정렬 우선순위를 정해주도록 한다.

람다식에 if문에 조건을 map.get(w1) == map.get(w2)를 주어 등장횟수가 같다면 내부에 if문에 조건을 w1.length() == w2.length()하여 단어의 길이가 같다면 return w1.compareTo(w2);하여 w1이 w2보다 사전 순으로 앞에 있다면 음수가 반환되어 정렬 시 앞쪽에 배치되도록 하고 뒤에 있다면 양수가 반환되어 정렬 시 뒤쪽에 배치되도록 한다.

단어 길이가 같지 않다면 return w2.length() - w1.length();하여 길이가 길수록 앞에 배치되도록 한다.

w1이 w2보다 길다면 음수가 반환되어 정렬 시 w1이 앞쪽에 배치될 것이고, w1이 w2보다 짧다면 양수가 반환되어 w1이 뒤쪽에 배치된다.

등장횟수가 같지 않다면 map.get(w2) - map.get(w1);하여 자주 등장하는 단어가 앞에 정렬되도록 한다.

w1이 w2보다 많이 등장한다면 음수가 반환되어 w1이 정렬 시 앞쪽에 배치되게 되고, w1이 w2보다 적게 등장한다면 양수가 반환되어 w1이 뒤쪽에 배치되게 된다.

 

이는 정렬 우선순위를 조금 확인하기 어려울 수 있으니 주석처리한 코드와 같이 if문을 우선순위가 높은 조건대로 먼저 써서 return하게 하는 방법도 있다.

if문에 조건을 map.get(w1) != map.get(w2)하여 등장횟수가 같지 않다면 return map.get(w2) - map.get(w1);하여 등장횟수가 많은 것이 앞쪽에 배치되도록 한다.

이후 if문에 조건을 w1.length() != w2.length()하여 단어의 길이가 같지 않다면 return w2.length() - w1.length();하여 단어의 길이가 긴 단어가 앞쪽에 배치되도록 한다.

그리고 앞써 2개의 if문이 끝나면 return w1.compareTo(w2);하여 사전순으로 앞에 있는 단어가 앞쪽에 배치되도록 한다.

이 같은 코드는 앞선 코드 방식보다 더 코드를 확인하기 쉽고 정렬 우선순위를 파악하기 쉽다.

 

foreach문을 사용해 StringBuilder sb에 정렬된 ArrayList의 요소들을 꺼내어 넣어주도록 한다.

sb를 출력한다.

 

🔹 결과

 

🔹 알게된 정보

    • HashMap 사용 시 getOrDefault()메서드를 사용하면 코드를 간결하게 할 수 있다.
    • 정렬 시 정렬 우선순위를 두번째 인자로 Comparator를 사용해 람다식으로 넣어주는 방법을 기억하자.
    • 정렬시 정렬 우선순위를 if문을 여러개를 써서 표현하는 방식이 더 코드를 이해하기 쉽다.
    • 정렬 시 return문에 w1과 w2의 배치를 잘 생각해보고 음수를 반환하면 앞쪽에 배치되고 양수를 반환하면 뒤쪽에 배치되는 것을 기억하자.

 


반응형
저작자표시 비영리 동일조건 (새창열림)

'Problem Solving (Java) > 백준' 카테고리의 다른 글

[백준] 25501번 : 재귀의 귀재 (브론즈 Ⅱ) - Java/자바  (2) 2025.07.04
[백준] 10870번 : 피보나치 수 5 (브론즈 Ⅱ) - Java/자바  (0) 2025.07.03
[백준] 2108번 : 통계학 (실버 Ⅱ) - Java/자바  (0) 2025.07.03
[백준] 11050번 : 이항 계수 1 (브론즈 Ⅰ) - Java/자바  (2) 2025.06.30
[백준] 10872번 : 팩토리얼 (브론즈 Ⅲ) - Java/자바  (0) 2025.06.30
'Problem Solving (Java)/백준' 카테고리의 다른 글
  • [백준] 25501번 : 재귀의 귀재 (브론즈 Ⅱ) - Java/자바
  • [백준] 10870번 : 피보나치 수 5 (브론즈 Ⅱ) - Java/자바
  • [백준] 2108번 : 통계학 (실버 Ⅱ) - Java/자바
  • [백준] 11050번 : 이항 계수 1 (브론즈 Ⅰ) - Java/자바
sunghyun.dev
sunghyun.dev
개발 공부를 기록하는 블로그입니다.
  • sunghyun.dev
    개발 공부 기록 블로그
    sunghyun.dev
  • 전체
    오늘
    어제
    • 전체 글 (61)
      • Problem Solving (Java) (51)
        • 백준 (51)
        • 프로그래머스 (0)
      • Computer Science (2)
        • 자료구조 (0)
        • 알고리즘 (2)
        • 컴퓨터 구조 (0)
        • 운영체제 (0)
        • 컴퓨터 네트워크 (0)
      • Language (7)
        • Java (7)
        • Kotlin (0)
        • Python (0)
      • Framework (0)
        • Spring (0)
        • Node.js (0)
        • Vue.js (0)
        • React (0)
      • DBMS (0)
        • 데이터베이스 (0)
        • MySQL (0)
        • Oracle (0)
        • MariaDB (0)
      • Git (0)
      • Web (0)
      • Cloud (0)
      • 자격증 (0)
        • SQLD (0)
        • 정보처리기사 (0)
        • 오픽 (0)
        • AICE (0)
      • Toy Project (0)
      • IDE (0)
        • IntelliJ IDEA (0)
      • 기타 (0)
      • Tistory (1)
  • 링크

    • Github
    • Notion
  • 블로그 메뉴

    • 홈
    • 방명록
    • 태그
  • 인기 글

  • 태그

    조합
    HashMap
    Comparator
    백준
    LCM
    덱
    재귀함수
    Deque
    Java
    카운팅정렬
    코딩테스트
    문자열
    알고리즘
    스택
    브루트포스
    유클리드호제법
    이진탐색
    gcd
    배열
    최대공약수
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
sunghyun.dev
[백준] 20920번 : 영단어 암기는 괴로워 (실버 Ⅲ) - Java/자바
상단으로

티스토리툴바