[JAVA] 방금그곡 - 프로그래머스 LV2

나길진·2023년 12월 27일
0

프로그래머스

목록 보기
7/9

해당 문제 링크

[3차] 방금그곡 - 프로그래머스 LV2

구현할 기능 목록

  1. 방송시간 구하기
  2. 방송시간만큼 악보 완성하기
  3. 악보에 네오가 기억한 멜로디(m)가 있는지 확인하기
  4. 존재하면 방송시간 비교 후 제일 긴 노래 제목 가져오기
  5. 없으면 (None)

방송시간만큼 악보 완성하기

악보의 한글자씩 탐색하다가 다음글자에 "#"이 존재하면 "#"을 붙여서 sb에 추가하고 음표 갯수(count)를 증가시킴. 음표 갯수가 방송시간 이상 되면 종료(방송시간 1분당 음표 1개이기 때문에)

소스코드

     public String createFullMusic(String music, int time){
        StringBuilder sb = new StringBuilder();
        int count = 0;
        int i = 0;
        while(count < time){
            char findChar = music.charAt(i % music.length());
            char nextChar = music.charAt((i+1) % music.length());
            sb.append(findChar);
            i++;
            
            if (nextChar == '#'){
                sb.append(nextChar);
                i++;
            }
            count++;
        }
        
        return sb.toString();
    }

악보에 네오가 기억한 멜로디(m)가 있는지 확인하기

처음엔 위에서 제작한 악보에 indexOf() 사용해서 체크하면 되겠지라는 생각으로 했는데 테스트에 통과하지 못했고 두가지 문제가 있었다.

  1. 제작한 악보가 "ABC#CCC" 일 때, 네오가 기억한 멜로디가 "ABC" 인 경우
    • 해당 악보는 맞는 악보가 아닌데에도 맞는 악보인 것으로 탐색함.
  2. 제작한 악보가 "ABC#ABC" 일 때, 네오가 기억한 멜로디가 "ABC" 인 경우
    • 뒤에 ABC를 찾아야 하지만 앞에 ABC를 찾음

이러한 이유로 while문으로 문자열을 잘라가면서 확인하는 메서드를 작성했다.

public boolean containMusicName(String fullMusic, String keyword){
    while(true){
        int findIndex = fullMusic.indexOf(keyword);
        if (findIndex < 0){
            return false;
        }
            
        //뒤에 더이상 글자가 없으면
        int searchIndex = findIndex + keyword.length();
        if (searchIndex >= fullMusic.length()){
            return true;
        }
            
        //뒤에 #이 아니면
        char nextChar = fullMusic.charAt(searchIndex);
        if (nextChar != '#'){
            return true;
        }
            
        fullMusic = fullMusic.substring(searchIndex);
    }   
}

소스코드

class Solution {
    public String solution(String m, String[] musicinfos) {
        String answer = "(None)";
        int answerMusicPlayTime = 0;
        
        for(int i=0; i<musicinfos.length; i++){
            String[] musicInfo = musicinfos[i].split(",");
            String start = musicInfo[0];
            String end = musicInfo[1];
            String musicName = musicInfo[2];
            String music = musicInfo[3];
            
            int musicPlayTime = calculateMusicPlayTime(start, end);
            String fullMusic = createFullMusic(music, musicPlayTime);
            
            boolean isContain = containMusicName(fullMusic, m);
            if (isContain){
            	// 방송시간이 제일 긴 음악 저장
                if (answerMusicPlayTime < musicPlayTime) {
                    answer = musicName;
                    answerMusicPlayTime = musicPlayTime;
                }
            }
        }
        
        return answer;
    }
    public boolean containMusicName(String fullMusic, String keyword){
        while(true){
            int findIndex = fullMusic.indexOf(keyword);
            if (findIndex < 0){
                return false;
            }
            
            //뒤에 더이상 글자가 없으면
            int searchIndex = findIndex + keyword.length();
            if (searchIndex >= fullMusic.length()){
                return true;
            }
            
            //뒤에 #이 아니면
            char nextChar = fullMusic.charAt(searchIndex);
            if (nextChar != '#'){
                return true;
            }
            
            fullMusic = fullMusic.substring(searchIndex);
        }   
    }
    public String createFullMusic(String music, int time){
        StringBuilder sb = new StringBuilder();
        int count = 0;
        int i = 0;
        while(count < time){
            char findChar = music.charAt(i % music.length());
            char nextChar = music.charAt((i+1) % music.length());
            sb.append(findChar);
            i++;
            
            if (nextChar == '#'){
                sb.append(nextChar);
                i++;
            }
            count++;
        }
        
        return sb.toString();
    }
    
    public int calculateMusicPlayTime(String start, String end){
        int result = 0;
        
        final String separator = ":";
        String[] startTime = start.split(separator);
        String[] endTime = end.split(separator);
        
        int startHour = Integer.parseInt(startTime[0]);
        int startMin = Integer.parseInt(startTime[1]);
        int endHour = Integer.parseInt(endTime[0]);
        int endMin = Integer.parseInt(endTime[1]);
        
        result += (endHour - startHour) * 60;
        result += endMin - startMin;
        
        return result;
    }
}

다른사람 풀이

인기가 높은 풀이를 보니 "#" 관련된 음표를 다른 글자로 치환해서 푸는 방법이 신박했다. 예를들면 "C#"을 1로 "D#"을 2로 바꿔서 처리하니까 #을 구분하는 로직이 없어지고 보다 간결하게 소스가 나왔다.

profile
백엔드 개발자

0개의 댓글

관련 채용 정보