쌓고 쌓다

[프로그래머스] [3차] 방금그곡 C++ 풀이 및 해설 본문

알고리즘/프로그래머스

[프로그래머스] [3차] 방금그곡 C++ 풀이 및 해설

승민아 2023. 8. 20. 01:34

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이 방법

생각해야하는 구현 부분은 크게 다음과 같다.

  1. 음악이 재생된 시간 구하기
    1. 00:00부터 음악 끝난 시간까지 재생된 분 단위를 구한다.
    2. 00:00부터 음악 시작 시간까지 재생된 분 단위를 구한다.
    3. 끝난 시간까지 분단위 - 시작 시간까지 분단위 = "재생 시간"이 된다.
  2. #붙는 음을 다른 문자로 변환하기
    1. 네오가 들은 음을 라디오에서 재생한 음과 비교해야한다.
    2. 라디오에서 재생한 음 문자열에서 네오가 들은 음 문자열을 찾기위해 #이 붙은 음을 한 문자열로 변환할 필요.
    3. 변환 안하면 ABC를 찾아야하는데 ABC#에서 일치한다고 잘못된 판단을 할 수 있다.
  3. 라디오에서 재생된만큼 악보 구하기
    1. 그냥 라디오(음악이 재생된 시간)에서 재생한 시간만큼 악보 문자열 인덱스 0부터 반복하며 라디오 악보를 완성해 나가면 된다.
    2. 라디오 악보에서 m을 찾자.
  4. 주어진 musicinfos 배열을 순서대로 탐색하기에 먼저 입력된 음악 제목은 생각하지 않아도 된다.
    1. 그러나 재생시간 제일 긴 음악 제목이 있기에 현재 답의 재생시간보다 클때만 답을 갱신해주자.

 

문자열 메서드 find, substr 공부해야겠다...

 

전체 코드

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

void convert(string &sheet) {
    map<char, char> m;
    m.insert({'C', 'Q'});
    m.insert({'D', 'R'});
    m.insert({'F', 'S'});
    m.insert({'G', 'T'});
    m.insert({'A', 'U'});
    
    for(int i=0; i<sheet.length(); i++) {
        if(sheet[i]=='#') { // '#' 발견시 '#' 앞의 문자를 변환하고 '#' 문자 제거
            sheet[i-1]=m[sheet[i-1]];
            sheet.erase(sheet.begin()+i);
            i--;
        }
    }
    
}

string solution(string m, vector<string> musicinfos) {
    string answer = "(None)";

    int answerPlayTime=-1;
    for(int i=0; i<musicinfos.size(); i++) {
        string title;
        string sheet;
        int playTime=0;
        //처음 "XX:XX,XX:XX" 형식은 고정되어있기에 바로 시간 뽑아낼 수 있다.
    
        playTime+=(musicinfos[i][6]-'0')*600;
        playTime+=(musicinfos[i][7]-'0')*60;
        playTime+=(musicinfos[i][9]-'0')*10;
        playTime+=musicinfos[i][10]-'0';

        playTime-=(musicinfos[i][0]-'0')*600;
        playTime-=(musicinfos[i][1]-'0')*60;
        playTime-=(musicinfos[i][3]-'0')*10;
        playTime-=musicinfos[i][4]-'0';
        
        for(int j=12; j<musicinfos[i].size(); j++) { // 제목, 악보 분리
            if(musicinfos[i][j]==',') {
                title = musicinfos[i].substr(12, j-12);
                sheet = musicinfos[i].substr(j+1);
                break;
            }
        }

        // 문자 하나하나 비교하는 find 함수 실행시 ABC를 찾아야하는데 ABC#에서 일치한다고 판별해버리니
        // C#들을 다른 문자 하나로 치환하는 과정이 필요함.
        convert(sheet);
        
        string radio;
        int idx=0; // 재생 시간만큼 라디오에서 재생된다.
        for(int j=0; j<playTime; j++) {
            radio+=sheet[idx++];
            if(idx==sheet.length())
                idx=0;
        }
        
        
        convert(m);
        if(radio.find(m)!=string::npos) { //먼저 입력된 음악부터 정답을 찾으므로 순서에 대한 정보는 생각하지 않아도 된다.
            if(answerPlayTime<playTime) { //현재 답의 재생시간보다 크다면
                answerPlayTime=playTime; //재생시간 갱신
                answer=title; //답 갱신
            }
        }
        
    }
    return answer; // substr, find 메서드 공부
}
Comments