💡Problem Solving/Programmers

[프로그래머스] 방금그곡 (Java)

gom20 2021. 11. 23. 21:22

문제

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

 

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

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

programmers.co.kr

 

풀이

왜 이렇게 말을 꼬아놨는지 문제를 이해하는데 너무 오래걸린다.  

이 문제는 단순 구현 문제로 어려운 문제는 아니다.

 

'#' 기호가 음악 매칭할 때 걸리적 거릴게 눈에 훤해서, 

애초에 내가 기억한 멜로디에서 해당 기호를 떼고 다 소문자로 치환해주었다.

 

MusicInfo는 클래스를 생성하였다. 이 때에도 '#'기호를 떼줘야 한다. 

문자열 덩어리 하나로 들어오기 때문에 split()함수로 다 떼줘서 전체 재생시간을 int형으로 구해야 한다.

전체 재생시간을 구했다면, 재생된 전체 music 스트링도 구할 수 있다. (while문 사용)

 

재생된 전체 music에 내가 기억한 멜로디가 있는지 체크한다. 

만약 매칭된다면 ArrayList에 add한다. 

 

매칭된 내용이 없다면 (None)출력

 

매칭된 내용이 있다면 ArrayList를 sorting 한다. 

나는 MusicInfo 클래스 내 comparable을 implements하여 compareTo를 오버라이딩하였다. 

이 때 재생시간 내림차순으로 정렬하고, 만약 재생시간이 같다면 입력 순으로 정렬하게끔 구현하였다.

 

그러면 ArrayList에 0번째 index에 있는 MusicInfo인스턴스의 title 값이 답이 된다.

 

소스코드

import java.util.*;
class MusicInfo implements Comparable<MusicInfo>{
    int no;
    int startTime; // minute
    int endTime; // minute
    int playTime; // minute
    String title;
    String music;
    String playedMusic;
    
    @Override
    public int compareTo(MusicInfo m){
        // 재생 시간 내림차순, 같다면 입력 순
        int rs = m.playTime - this.playTime;
        if(rs == 0) rs = this.no = m.no;
        return rs;
    }
    
    public MusicInfo(String s, HashMap<String, String> map, int i){
        String[] arr = s.split(",");
        String[] start = arr[0].split(":");
        String[] end = arr[1].split(":");
        this.no = i;
        this.startTime = Integer.parseInt(start[0])*60 + Integer.parseInt(start[1]);
        this.endTime =  Integer.parseInt(end[0])*60 + Integer.parseInt(end[1]);
        this.playTime = endTime-startTime+1;
        this.title = arr[2];
        this.music = arr[3];
        removeSharp(map);
        setPlayedMusic();
    } 

    public boolean match(String m){
        // 재생된 전체 음악 스트링에 해당 멜로디가 있는지 체크
        if(playedMusic.contains(m)) return true;
        return false;
    }
    
    // 실제로 재생된 음악 스트링 전체 구하기
    private void setPlayedMusic(){
        int idx = 1;
        int mIdx = 0;
        int mLen = this.music.length();
        String ans = "";
        while(idx <= playTime){
            ans += this.music.charAt(mIdx);
            mIdx++;
            idx++;
            if(mIdx == mLen) mIdx = 0;
        }
        this.playedMusic = ans;
    }
    
    private void removeSharp(HashMap<String, String> map){
        for(String key : map.keySet()){
            this.music = this.music.replaceAll(key, map.get(key));
        }      
    }
}

class Solution {
    public String solution(String m, String[] musicinfos) {
        String answer = "";
        
        // # 있으면 골치아프다. 미리 대체하고 시작하자.
        String[] melody = new String[]{"C#", "D#", "F#","G#", "A#"};     
        String[] alternative = new String[]{"c", "d", "f", "g", "a"};
        HashMap<String, String> map = new HashMap<String, String>();
     
        // 내가 기억한 멜로디 # 없애기
        for(int i = 0 ; i < melody.length; i++) {
            map.put(melody[i], alternative[i]);
            m = m.replaceAll(melody[i], alternative[i]);
        }        
        // MusicInfo 클래스 생성, 내가 기억한 멜로디와 매치 하는 musicInfo만 list에 넣기
        ArrayList<MusicInfo> list = new ArrayList<MusicInfo>();
        for(int i = 0; i < musicinfos.length; i++){
            MusicInfo musicInfo = new MusicInfo(musicinfos[i], map, i);
            if(musicInfo.match(m)){
                list.add(musicInfo);
            }
        }
        if(list.isEmpty()) return "(None)";
        Collections.sort(list);
        return list.get(0).title;
    }
}