감자는 아직 꿈을 꾼다.

[알고리즘 기본 스킬 - Java] 복잡한 정렬 본문

카테고리 없음

[알고리즘 기본 스킬 - Java] 복잡한 정렬

dreaming-potato 2024. 11. 21. 16:37

아아아아아

자바에서 조건들이 주어졌을 때, 우선순위대로 정렬해서 출력하는 방법에 대해서 소개하겠습니다.

 

2024년 하반기 현대자동차 소프티어 코테를 어제 봤습니다. 

5문제는 최장거리(그래프), 큐, 정렬 등 있었는 데 완전 처음 본 문제도 있었습니다. 

그 중 3문제정도 풀고, 테스트케이스 통과했길래 그냥 제출했습니다.

(화장실이 너무 급한데 중간에 갈수가없어서 정신이 없었습니다 ㅜㅜ )

하지만 문제를 풀고 보니 제가 푼 방식이 틀렸더군요... 

그 문제가 복잡하다기 보단 간단한 정렬에 관한 문제였습니다.

 

 

그래서 이 참에 완벽하게 알아가기 위해서 정리하려고 글을 작성하게되었습니다. 

(분노의 짤의 이유죠)

 

자바는 기본적으로 Comparable, Comparator 인터페이스를 제공합니다.

 

정리한 글 

https://dreaming-potato.tistory.com/entry/%EA%BC%AC%EA%BC%AC%EB%AC%B4-%EC%9E%90%EB%B0%94-Comparable-vs-Comparator

 

[꼬꼬무-자바] Comparable vs Comparator

Comparable 와 Comparator클래스의 데이터 멤버를 사용해서 객체를 정렬하기 위한 인터페이스간단한게 표현하면 이렇다.자바의 기본 자료형들로 Collection이나 Array가 이루어져 있을 경우 기본적인 sort

dreaming-potato.tistory.com

 

사실 이것을 사용하면 간단하게 문제를 해결 할 수있습니다. 

Comparable 객체를 생성한다음 thenComparing이라는 메소드를 사용해서 해결하는 것이죠

thenComparing은 예를 들어서 이름순으로 정렬하고 이름이 같으면, 나이순으로 정렬해줘 

이런 경우에서 사용됩니다.

이름이 같은 거 정렬.thenComparing(나이순) 이렇게 사용됩니다.

너무 간단하지요~~ 저는 어제만 해도 몰랐었습니다.

 

사실 문제가 전부 다 상세하게 기억이 나지만 작성하진 않겠습니다.

그냥 코드를 보면서 이해하셔도 충분할 것같고 주석에 어느정도 달아놨습니다.

 

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

class Main {
	static class Human {
		char sex;
		long age;
		String role;

		public Human(char sex, long age, String role) {
			this.sex = sex;
			this.age = age;
			this.role = role;
		}

		@Override
		public String toString() {
			String role = this.role == null ? "" : this.role;
			return this.sex + " " + this.age + " " + role;
		}
	}

	public static void main(String[] ags) throws IOException {
		// 입력 받기
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int[] prior = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
		int N = Integer.parseInt(br.readLine());
		
		HashMap<String,Integer> map = new HashMap<>();
		map.put("PW", 1);
		map.put("DP", 2);
		map.put("P", 3);
		
		ArrayList<Human> arr = new ArrayList<>();
		for (int i = 0; i < N; i++) {
			String[] inputs = br.readLine().split(" ");
			char sex = inputs[0].charAt(0);
			Long age = Long.parseLong(inputs[1]);
			if (inputs.length == 2) {
				arr.add(new Human(sex, age, null));
			} else {
				arr.add(new Human(sex, age, inputs[2]));
			}

		}
		// 기본적인 Comparator 체인 생성
		Comparator<Human> comp = (a, b) -> 0;
		// 연결
		for (int i = 0; i < 3; i++) {
			// 7세 이하일 경우 어릴 수록 우선순위 제일 높음
			// 8세 이상부터는 나이 많을 수록 우선순위 높다
			if (prior[i] == 1) {
				comp = comp.thenComparing((a,b) -> {
					if ( a.age <= 7 || b.age<= 7) return Long.compare(a.age,b.age);
					return Long.compare(b.age, a.age);
				});
			}
			// F > M
			else if (prior[i] == 2) {
				comp = comp.thenComparing((a,b) -> {
					return Character.compare(a.sex, b.sex);
				});
			}
			// PW > DP > P 
			else if (prior[i] == 3) {
				comp = comp.thenComparing((a,b) -> {
					int aRole = a.role == null ? 4 : map.get(a.role);
					int bRole = b.role == null ? 4 : map.get(b.role);
					return Integer.compare(aRole, bRole);
				});
			}
		}
		arr.sort(comp);
		StringBuilder sb = new StringBuilder();
		for (Human h : arr) {
			sb.append(h).append("\n");
		}
		System.out.println(sb);

	}
}