[문제보기]

 2018 KAKAO BLIND. 방금 그 곡

 

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

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

programmers.co.kr

 

[풀이과정]

프로그래머스 문제를 풀려면 일단 입력값들을 잘 주무를 수 있어야 한다. 해서 필자는 vector형태로 반환을 하는 

strtok()함수를 새로 만들어서 입력값을 나누었다. 

 

strtok() 

- delim을 기준으로 string s값을 나눠주는 함수이다. 여기서 delim의 Default값은 ' '(공백)이 된다. 

  필자는 반환값을 vector<string>로 받기 위해 <cstring>에 있는 함수가 아닌 새로 만들었다.

  <cstring>에 있는 strtok() 함수는 반환값이 'char형'

 

그리고 m과 musicinfos의 값에서 C#, D#, F#, G#, A#들을 길이가 2가 되고, 이 부분을 구별하기 어렵기 때문에, 애초에 입력값으로 사용이 안돼는 c, d, f, g, a값으로 치환을 해주었다.

 

musicinfos에서 뽑아낸 입력값중에 0 번째와 1 번째가 시간을 뜻하기 때문에 이를 통해 음악이 재생된 길이를 알아내서, 음악이 재생된 시간만큼 악보를 반복해서 저장해준다. 

 

그리고 flag를 사용해서 각 음악들의 악보에 m값이 들어있는지 확인을 하고, 적어도 하나가 있으면 flag는 true값을

가지게 되어, 조건에 맞춰 출력값을 찾아주게 된다. flag가 false값을 가지면 맞는 음악이 없으므로 "(None)"을 출력한다.

 

조건을 맞출때는 sort함수를 사용했는데, 이를 통해 음악의 길이를 기준으로 내림차순으로 정렬을 했다. 

여기서 second값으로 들어가는 음악 제목에 대해서는 정렬을 무시했는데 이는, 조건에서 음악의 길이가 같을 경우

먼저 들어온 음악이 출력이 된다고 했기 때문에 정렬을 안 시켜주었다.

[소스코드]

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

bool cmp(pair<int, string> a, pair<int, string> b){
    return a.first > b.first;
}

vector<string> strtok(string s, char delim = ' '){
    vector<string> ret;
    
    int prev = 0;
    for(int i=0; i< s.size(); i++){
        if(s[i] == delim){
            ret.push_back(s.substr(prev, i-prev));
            prev = i+1;
        }
    }
    
    if(prev != s.size())
        ret.push_back(s.substr(prev, s.size()-prev));
    
    return ret;
}

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

    string a = "";
    for(int i=0; i<m.size(); i++){
        if(m[i+1] == '#'){
            a += (m[i]+32);
            i++;
            continue;
        }
        a += m[i];
    }
    m = a;

    vector<vector<string>> info;
    for(int i=0; i<musicinfos.size(); i++){
        vector<string> temp = strtok(musicinfos[i], ',');
        
        int time = (stoi(strtok(temp[1], ':')[0]) - stoi(strtok(temp[0], ':')[0]))*60 + 
            (stoi(strtok(temp[1], ':')[1]) - stoi(strtok(temp[0], ':')[1]));
        string s = "";
        for(int i=0; i<temp[3].size(); i++){
            if(temp[3][i+1] == '#'){
                s += (temp[3][i] + 32);
                i++;
                continue;
            }
            s += temp[3][i];
        }
        temp[3] = s;
        int size = temp[3].size();
        s = "";
        for(int i=0; i<time; i++){
            s += temp[3][i%size];
        }
        info.push_back({temp[2], s, to_string(time)});
    }

    bool flag;
    vector<pair<int, string>> ans;
    for(int i=0; i<info.size(); i++){
        flag = false;
        for(int j=0; j<info[i][1].size(); j++){
            int cnt = 0, idx = j;
            while(1){
                if(info[i][1][idx++] != m[cnt++]){
                    break;
                }
                if(cnt == m.size()){
                    flag = true;
                    break;
                }
            }
            if(flag){
                ans.push_back({stoi(info[i][2]), info[i][0]});
                break;
            }
        }
    }

    if(!ans.empty()){
        sort(ans.begin(), ans.end(), cmp);
        answer = ans[0].second;
        return answer;
    }
    else{
        answer = "(None)";
        return answer;
    }
}

 

[해결 과정 중 실수한 부분]

코드는 많이 길어지고, 중간 부분이 좀 더러워졌지만, 그래도 로직상으로 틀린 부분은 없다고 생각했는데, 계속

90%만 맞게 나왔다. 그래서 다른 블로그도 참고를 하고 계속 코드를 봤는데 찾지를 못했다. 하나 하나씩 손으로 그려가던중 sort()함수를 사용하는 부분에서 머리속으로는 내림차순으로 했다고 생각했는데, 오름차순으로 정렬을 시켜서 계속

90%가 나왔던 것이였다. 내림차순으로 정렬을 다시 해주니 100% 정답이 나왔다.

 

- 추가 - 

strtok() 함수 로직을 머리속에 넣어야겠다. 

프로그래머스 문제를 풀면서 입력값에 대해 다루는게 힘들었는데 strtok() 함수를 사용하니 편했다. 

이는 추석 트래픽 문제를 풀면서 다른 블로그를 참고를 해서 가져온 코드이다. 

 

vector<string> strtok(string s, char delim = ' '){

 vector<string> ret;

 

 int prev = 0;

 for(int i=0; i<s.size(); i++){
  if(s[i] == delim){

     ret.push_back(s.substr(prev, i-prev);

     prev = i+1;

   }

 }

 

if(prev != s.size())

   ret.push_back(s.substr(prev, s.size()-prev);

 

 return ret;

}

 

원래 <cstring> 라이브러리에 있는 strtok()함수는 char형으로 반환을 해주는데,

필자는 vector<string>형으로 반환을 해주기 위해 새로 만들었다.

 

medium.com/@dltkddud4403/2018-카카오-블라인드-코딩테스트-추석-트래픽