스터디원을 통해 새롭게 알게된 comparing을 적용한 풀이법을 정리하려고 합니다.
이 문제는 스터디원을 통해 새롭게 알게된 comparing을 적용한 풀이법과
제가 원래 풀었던 풀이법 두 가지를 정리하겠습니다.
먼저 새롭게 알게된 comparing입니다.
자바8의 람다를 이용한 다중조건 정렬입니다.
아래와 같이 길어진 코드를
//2. comparator
Comparator<Cost> comp = new Comparator<>(){
@Override
public int compare(Cost c1, Cost c2){
if(c1.length != c2.length){
return c1.length - c2.length;
}else{
return c1.x-c2.x;
}
}
};
Collections.sort(list,comp);
아래와 같이 간단하게 표현할 수 있습니다.
// 길이 오름차순, 길이가 같으면 x 오름차순
list.sort(Comparator.comparing(Cost::getLength).thenComparing(Apple::getX));
물론 이와 같이 표현하려면 아래와 같은 내부 클래스에 메서드를 선언해야 합니다.
class Solution {
static class Cost{
int x;
int y;
int length;
public Cost(int x, int y, int length){
this.x=x;
this.y=y;
this.length = length;
}
public int getLength(){
return length;
}
public int getX(){
return x;
}
}
...
import java.util.*;
class Solution {
static class Cost{
int x;
int y;
int length;
public Cost(int x, int y, int length){
this.x=x;
this.y=y;
this.length = length;
}
}
public ArrayList<Integer> solution(int[] sequence, int k) {
ArrayList<Cost> list = new ArrayList<>();
ArrayList<Integer> answer = new ArrayList<>();
// 기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열
// 부분 수열의 합은 k
// 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은
// 길이가 짧은 수열 여러게 앞쪽에 나오는 수열
// 시작 인덱스와 마지막 인덱스
//1. 투포인터
int r=0;
int l=0;
int sum = sequence[0];
while(true){
if(sum==k){
list.add(new Cost(l,r,r-l+1));
}
if(r == sequence.length && l == sequence.length) break;
if(sum<= k && r< sequence.length){
r++;
if(r<sequence.length){
sum+=sequence[r];
}
}else{
if(l<sequence.length) sum-=sequence[l];
l++;
}
}
//2. comparator
Comparator<Cost> comp = new Comparator<>(){
@Override
public int compare(Cost c1, Cost c2){
if(c1.length != c2.length){
return c1.length - c2.length;
}else{
return c1.x-c2.x;
}
}
};
Collections.sort(list,comp);
Cost target = list.get(0);
answer.add(target.x);
answer.add(target.y);
return answer;
}
}
import java.util.*;
class Solution {
static class Cost{
int x;
int y;
int length;
public Cost(int x, int y, int length){
this.x=x;
this.y=y;
this.length = length;
}
public int getLength(){
return length;
}
public int getX(){
return x;
}
}
public ArrayList<Integer> solution(int[] sequence, int k) {
ArrayList<Cost> list = new ArrayList<>();
ArrayList<Integer> answer = new ArrayList<>();
// 기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열
// 부분 수열의 합은 k
// 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은
// 길이가 짧은 수열 여러게 앞쪽에 나오는 수열
// 시작 인덱스와 마지막 인덱스
//1. 투포인터
int r=0;
int l=0;
int sum = sequence[0];
while(true){
if(sum==k){
list.add(new Cost(l,r,r-l+1));
}
if(r == sequence.length && l == sequence.length) break;
if(sum<= k && r< sequence.length){
r++;
if(r<sequence.length){
sum+=sequence[r];
}
}else{
if(l<sequence.length) sum-=sequence[l];
l++;
}
}
//2. comparing()
list.sort(Comparator.comparing(Cost::getLength).thenComparing(Cost::getX));
Cost target = list.get(0);
answer.add(target.x);
answer.add(target.y);
return answer;
}
}
이 문제에서 comparing()이 하나가 내림차순이고 그 값이 같으면 오름차순이다를 적용하기 위한 방법을 소개해보려고 합니다.
두 개의 조건의 정렬 방식이 섞인 경우에 어떻게 표현해야 할까요?
다음과 같이 내부 클래스가 선언되어져 있고
import java.util.*;
class Solution {
static int MaxTime = 24*60;
static class Music{
//재생시간, 위치, 제목
int time;
int index;
String title;
public Music(int time, int index, String title){
this.time = time;
this.index= index;
this.title = title;
}
public int getTime(){
return time;
}
public int getIndex(){
return index;
}
}
길이가 내림차순, 순서 오름차순이라면
Comparator<Music> reversedComparator = Comparator.comparing(Music::getTime).reversed();
list.sort(reversedComparator.thenComparing(Music::getIndex));
반대라면
// 무게 오름차순 정렬 (무게가 같으면 색 내림차순 정렬)
Comparator<Apple> reversedColorComparator =Comparator.comparing(Apple::getColor).reversed();
inventory.sort(Comparator.comparing(Apple::getWeight).thenComparing(reversedColorComparator));
import java.util.*;
class Solution {
static int MaxTime = 24*60;
static class Music{
//재생시간, 위치, 제목
int time;
int index;
String title;
public Music(int time, int index, String title){
this.time = time;
this.index= index;
this.title = title;
}
public int getTime(){
return time;
}
public int getIndex(){
return index;
}
}
public String solution(String m, String[] musicinfos) {
String answer = "";
// TV, 라디오 등에서 나온 음악에 관해 제목 등의 정보를 제공
// 음악 제목, 재생이 시작되고 끝난시각, 악보
// 사용되는 음 : C, C#, D, D#, E, F, F#, G, G#, A, A#, B - 1분에 1개씩 재생
// 음악의 길이 < 재생된 시간 - 음악이 끊김 없이 처음부터 반복 재생
// 음악 길이 > 재생된 시간 - 음악이 처음부터 시간만큼만 재생
// 음악이 00:00 넘어서 재생안됨
// 조건이 일치하는 음악 여러개-> 라디오에서 재생된 시간이 제일 긴 음악 제목 -> 재생된 시간이 같을 경우 -> 먼저 입력
// 조건 일치하는 음악 X->'(NONE)'
//m: 음
//musicinfos : 100개 이하의 곡 - 음악 시작 시각, 끝난 시각, 음악제목, 악보 정보
// 1. 재생된 시각과 끝난 시각을 계산해서 악보를 만든다
// 2. 같은 문장이 등장하면 길,재생시간, 위치, 제목 (여기서 같은 문장이라는 것은 ABC#의 경우도 생각할 것)
ArrayList<Music> list = new ArrayList<>();
for(int i=0;i<musicinfos.length;i++){
String[] music = musicinfos[i].split(",");
// 시작 시간
String[] start_time = music[0].split(":");
int start= Integer.parseInt(start_time[0])*60 + Integer.parseInt(start_time[1]);
// 끝나는 시간
String[] end_time = music[1].split(":");
int end = Integer.parseInt(end_time[0])*60 + Integer.parseInt(end_time[1]);
//재생시간
int totalTime = end-start;
if(totalTime> MaxTime) totalTime = MaxTime;
//#을 대체 문자로 바꿔버리기
m = removeShap(m);
music[3]=removeShap(music[3]);
// 악보 만들기
String sheet = makeSheet(totalTime,music[3]);
// 악보에 기억한 음악이 들어있으면
if(searchM(m,sheet)){
list.add(new Music(totalTime,i,music[2]));
}
}
//기억한 음악이 악보에 없는 경우
if(list.size()==0) return "(None)";
//길이가 내림차순, 순서 오름차순
Comparator<Music> reversedComparator = Comparator.comparing(Music::getTime).reversed();
list.sort(reversedComparator.thenComparing(Music::getIndex));
return list.get(0).title;
}
//# 붙어있는 음 대체하기
static String removeShap(String input){
input=input.replace("C#","H");
input=input.replace("D#","I");
input=input.replace("F#","J");
input=input.replace("G#","K");
input=input.replace("A#","L");
return input;
}
//악보만들기
static String makeSheet(int totalTime, String music){
StringBuilder sb = new StringBuilder();
String sheet="";
sb.append(music);
while(true){
if(totalTime<=sb.length()){
sheet=sb.substring(0,totalTime);
break;
}else{
sb.append(music);
}
}
return sheet ;
}
// 기억한 음악이 악보에 있는지 확인
static boolean searchM(String m, String sheet){
//제거된 개수
int remove = sheet.length() - sheet.replace(m,"").length();
//제거된 개수가 기억한 음악의 길이와 같거나 크다면 등장한 것이다!
if(remove>=m.length()) return true;
return false;
}
}