반응형

문제출처

https://programmers.co.kr/learn/courses/30/lessons/17686

 

코딩테스트 연습 - [3차] 파일명 정렬

파일명 정렬 세 차례의 코딩 테스트와 두 차례의 면접이라는 기나긴 블라인드 공채를 무사히 통과해 카카오에 입사한 무지는 파일 저장소 서버 관리를 맡게 되었다. 저장소 서버에는 프로그램��

programmers.co.kr

문제풀이

Java에서 사용자 정의로 정렬을 진행할때 Comparator를 사용한다. 이 문제는 Comparator를 사용할 줄 아는지 묻는 문제이다. 파일명을 head, number, tail로 분리한뒤 정렬을 다음 순서에 맞게 진행하면 된다.

head를 기준으로 문자열 오름차순으로 먼저 정렬한다. 이 때 대소문자 구분을 하지 않기 때문에 본인은 소문자로 통일한뒤 진행했다. head가 같은경우 number로 정렬하고 number도 같다면 기존 files의 순서를 지키면 된다.

 

풀이 자체가 Comparator 인터페이스를 구현하고 있다. 정렬을 할때 Comparator와 Comparable을 사용하곤 하는데 자세한 내용은 https://swjeong.tistory.com/198?category=778818 이 글을 참조하면 된다.

 

소스코드

https://github.com/sw93/algorithm/blob/master/Programmers/%EC%B9%B4%EC%B9%B4%EC%98%A4%20-%20%ED%8C%8C%EC%9D%BC%EB%AA%85%20%EC%A0%95%EB%A0%AC.java

 

sw93/algorithm

problem solve. Contribute to sw93/algorithm development by creating an account on GitHub.

github.com

 

import java.util.*;
class Solution {
    public String[] solution(String[] files) {
        
        Arrays.sort(files, new Comparator<String>() {
           public int compare(String s1, String s2) {
               String head1 = s1.split("[0-9]")[0];
               String head2 = s2.split("[0-9]")[0];
               s1 = s1.replace(head1, "");
               s2 = s2.replace(head2, "");
               
               head1 = head1.toLowerCase();
               head2 = head2.toLowerCase();
               
               // compareTo(x, y) => [ -1 : x < y | 0 : x == y | 1 : x > y ]
               int headCompareValue = head1.compareTo(head2);
               if (headCompareValue == 0) {
                   
                  // head정렬 값이 같으므로 number로 정렬
                  String num1 = "";
                  for (char c : s1.toCharArray()) {
                      if (!(c >= '0' && c <= '9')) break;
                      num1 += c;
                  }
                  String num2 = "";
                  for (char c : s2.toCharArray()) {
                     if (!(c >= '0' && c <= '9')) break;
                     num2 += c;
                  }
                  return (Integer.parseInt(num1) - Integer.parseInt(num2));
               } else {
                   return headCompareValue;
               }
           }
        });
        
        return files;
    }
}
반응형
반응형

Comparable, Comparator 모두 자바에서 정렬을 할 때 사용하고 있습니다. 하지만 이 2가지는 명확한 차이가 존재합니다.

2가지 모두 정렬할 때 비교해 객체의 순서를 결정하는 역할을 합니다. 이 2가지 인터페이스를 사용하면 Collections.binary.Search, Collections.binarySearch, Collections.max, Collections.min, Collections.sort, Arrays.binarySearch, Arrays.sort같은 순서를 결정하는 메소드를 사용할 수 있습니다.

결론적으로 Comparable과 Comparator의 차이는 다음과 같습니다.

 

* Comparable - 기준을 설정하고 정렬. 즉, 특정한 기준 1가지를 가지고 정렬 Ex) 학점을 기준으로 오름차순 or 내림차순

* Comparator - Comparable과 다르게 요구사항에서 주어진 특정 기준을 가지고 정렬 Ex) 학점이 같다면 이름순으로 정렬

 

그럼 Comparable과 Comparator의 2가지 차이점을 알아보겠습니다.

 

 

- Comparable

Comparable은 compareTo 메서드를 오버라이드 합니다. 

Comparable을 구현한 클래스는 기본적으로 오름차순을 기준으로 정렬을 수행합니다. 또한 1가지 기준점을 가지고 그에 대해 정렬을 하고 싶을 때 사용합니다.

 

- Comparator

Comparator는 compare 메서드를 오버라이드 합니다.

Comparator를 구현한 클래스는 일반적인 정렬기준을 넘어 사용자 정의 조건을 규칙으로 정렬을 하고 싶을 때 사용합니다.

 

 

정리하면 Comparable은 기본적인 정렬위주일 때 사용하고 특정한 규칙을 사용해 정렬을 하고 싶을 때는 Comparator를 사용하면 됩니다.

반응형
반응형

문제출처

https://programmers.co.kr/learn/courses/30/lessons/17683

 

코딩테스트 연습 - [3차] 방금그곡

방금그곡 라디오를 자주 듣는 네오는 라디오에서 방금 나왔던 음악이 무슨 음악인지 궁금해질 때가 많다. 그럴 때 네오는 다음 포털의 '방금그곡' 서비스를 이용하곤 한다. 방금그곡에서는 TV, ��

programmers.co.kr

 

문제풀이

문제에서 주어진 조건대로 문자열 처리를 하고 구현하면 되는 문제다. 여기서 핵심은 #이 붙은 문자 처리 방법이라고 생각한다. 본인은 #이붙은 문자를 convertSound(String m) 메서드를 통해 소문자로 치환한뒤 구현했다. 또한 나중에 악보를 생성할때를 생각해서 곡의 재생시간을 구할때 단위를 분으로 통일했다.

 

이 문제는 오해의 소지가 있다고 생각한다. 지문에서 `(None)`을 리턴한다고 했는데 실제로는 `(None)`이 아니라 (None)을 리턴해줘야 하기 때문이다.

 

소스코드

https://github.com/sw93/algorithm/blob/master/Programmers/%EC%B9%B4%EC%B9%B4%EC%98%A4%20-%20%EB%B0%A9%EA%B8%88%EA%B7%B8%EA%B3%A1.java

 

sw93/algorithm

problem solve. Contribute to sw93/algorithm development by creating an account on GitHub.

github.com

 

class Solution {

    // #이 붙은 음을 소문자로 치환
    private String convertSound(String m) {
        m = m.replaceAll("C#", "c");
        m = m.replaceAll("D#", "d");
        m = m.replaceAll("F#", "f");
        m = m.replaceAll("G#", "g");
        m = m.replaceAll("A#", "a");
        
        return m;
    }
    
    // 곡의 재생시간을 분으로 환산
    private int getRunningTime(String startInfo, String endInfo) {
        int runningTime = 0;
        int startHour = Integer.parseInt(startInfo.split(":")[0]);
        int startMinute = Integer.parseInt(startInfo.split(":")[1]);
        int endHour = Integer.parseInt(endInfo.split(":")[0]);
        int endMinute = Integer.parseInt(endInfo.split(":")[1]);
        
        return (endHour - startHour) * 60 + (endMinute - startMinute);
    }
    
    // 재생 시간만큼 재생해 악보를 만듬
    private String playMusic(String sound, int runningTime) {
        StringBuilder sb = new StringBuilder();
        int soundLength = sound.length();
        for (int i=0; i<runningTime; i++) {
            sb.append(sound.charAt(i % soundLength));
        }
        return sb.toString();
    }
    
    public String solution(String m, String[] musicinfos) {
        String answer = "(None)";
        m = convertSound(m);
        
        int maxRunningTime = 0;
        for (String info : musicinfos) {
            String[] musicInfo = info.split(",");
            int runningTime = getRunningTime(musicInfo[0], musicInfo[1]);
            String musicName = musicInfo[2];
            String sound = convertSound(musicInfo[3]);
            
            // 곡 정보를 재생해서 만든 악보
            String music = playMusic(sound, runningTime);
            
            // 정보를 통해 만든 악보가 기억한 악보와 다르다면 제외
            if (!music.contains(m)) continue;
            
            // 악보가 같은경우 재생시간이 긴 제목을 반환
            if (runningTime > maxRunningTime) {
                answer = musicName;
                maxRunningTime = runningTime;
            }
        }
        return answer;
    }
}
반응형

+ Recent posts