[java] 여러 기준으로 정렬하기

Seongho·2023년 12월 7일
0

java

목록 보기
9/11

#자바 여러 기준 정렬 , #자바 다중 기준 정렬

intro...

코딩테스트 문제를 풀다 보면 컬렉션을 여러 기준으로 정렬할 일이 많이 생긴다.
그 방법을 알아보자.

interface Comparable (java.lang)

자바 공식 문서 Comparable

compareTo(T o) 매서드 하나가 선언되어 있다.

interface Comparator (java.util)

자바 공식 문서 Comparator

compare(T o1, T o2) 매서드를 오버라이딩 하면 된다.

위 두 인터페이스에 관하여..

이 인터페이스들은 이름과 같이 객체를 비교하는 기능을 가진 인터페이스이다. 클래스에는 여러 필드가 있다. 이 클래스를 대소비교를 한다고 하면 어떤 기준으로 해야 하는지 모호하다.
따라서, 이 인터페이스를 사용함으로써 객체의 대소비교가 가능해진다.

  • Comparable(T o) : 파라미터로 받은 객체와 자신을 비교
  • Comparator(T o1, T o2) : 파라미터로 받은 두 객체를 비교

문제

백준 20920 자바

풀이 (Comparable 구현)

단어 하나 당 담겨야 하는 정보는 "단어, 등장 횟수" 이다. 그래서 클래스를 만들었다.

 public static class Word implements Comparable<Word>{
        String name;
        int cnt;
//
        public Word(String name) {
            this.name = name;
            cnt = 1;
        }

이제 자주 나오는 순, 길이가 긴 순, 알파벳 사전 순 으로 정렬을 해야 한다.

public static class Word implements Comparable<Word>{
        String name;
        int cnt;
        
        public Word(String name) {
            this.name = name;
            cnt = 1;
        }

        @Override
        public int compareTo(final Word o) {

            if(this.cnt != o.cnt){
                if(this.cnt > o.cnt) return -1;
                else if(this.cnt == o.cnt) return 0;
                else return 1;
            }
            if(this.name.length() != o.name.length()){
                if(this.name.length() > o.name.length()) return -1;
                else if(this.name.length() == o.name.length()) return 0;
                else return 1;
            }
            return this.name.compareTo(o.name);     //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
        }

풀이 (Comparator 구현)

Collections.sort(list, new Comparator<Word>() {
            @Override
            public int compare(Word o1, Word o2) {

                if(o1.cnt != o2.cnt){
                    if(o1.cnt > o2.cnt) return -1;
                    else if(o1.cnt == o2.cnt) return 0;
                    else return 1;
                }
                if(o1.name.length() != o2.name.length()){
                    if(o1.name.length() > o2.name.length()) return -1;
                    else if(o1.name.length() == o2.name.length()) return 0;
                    else return 1;
                }
                return o1.name.compareTo(o2.name);     //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
            }
        });

전체 코드

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

import java.util.*;

public class Main {

    public static class Word{
        String name;
        int cnt;

        public Word(String name) {
            this.name = name;
            cnt = 1;
        }

        //        @Override
//        public int compareTo(final Word o) {
//
//            if(this.cnt != o.cnt){
//                if(this.cnt > o.cnt) return -1;
//                else if(this.cnt == o.cnt) return 0;
//                else return 1;
//            }
//            if(this.name.length() != o.name.length()){
//                if(this.name.length() > o.name.length()) return -1;
//                else if(this.name.length() == o.name.length()) return 0;
//                else return 1;
//            }
//            return this.name.compareTo(o.name);     //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
//        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
        int n = Integer.parseInt(stringTokenizer.nextToken());
        int wordSize = Integer.parseInt(stringTokenizer.nextToken());
        Map<String, Word> map = new HashMap<>();

        List<Word> list = new ArrayList<>();
        for(int i = 0; i < n; i++){
            String str = bufferedReader.readLine();

            if(str.length() < wordSize) continue;

            if(map.containsKey(str)){
                map.get(str).cnt++;
            }
            else{
                Word word = new Word(str);
                map.put(str, word);
                list.add(word);
            }
        }

        Collections.sort(list, new Comparator<Word>() {
            @Override
            public int compare(Word o1, Word o2) {

                if(o1.cnt != o2.cnt){
                    if(o1.cnt > o2.cnt) return -1;
                    else if(o1.cnt == o2.cnt) return 0;
                    else return 1;
                }
                if(o1.name.length() != o2.name.length()){
                    if(o1.name.length() > o2.name.length()) return -1;
                    else if(o1.name.length() == o2.name.length()) return 0;
                    else return 1;
                }
                return o1.name.compareTo(o2.name);     //String.class의 compareTo() 매개변수가 사전순 앞에 있으면 1
            }
        });


        StringBuilder stringBuilder = new StringBuilder("");
        for(Word word : list){
            stringBuilder.append(word.name);
            stringBuilder.append("\n");
        }

        System.out.println(stringBuilder.toString());
    }
}
profile
Record What I Learned

0개의 댓글