1. 문제 및 예제
문자열과 구현이 합쳐진 문제 같았다. 꼼꼼했다면 더 쉽게 풀 수 있었을 것 같았는데, 놓친부분이 있어 시간이 오래 걸린 문제다.
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
2. 풀이
해당 문제는 문자열이 반복되기 때문에 두개를 표현하는 문자열 C#, D#, F#, G#, A#를 하나의 특정한 값으로 교체 하였다. 나같은 경우 그냥 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" 순서대로 1부터 9까지 그리고 뒤의 두개의 음을 A와 B로 즉, 고유한 값으로 변환하였다.
이런 전처리가 끝났다면 별로 어렵지 않은 문제다. 단계별로 나누면 다음과 같다.
1. info의 각 원소대로 for문을 돌린다.
1.1 한 문자열을 ',' 기준으로 나눈다.
1.2 시작 시간과 끝 시간을 사용하여 재생 시간을 구한다.
1.3 음들을 다시 한 문자당 하나의 음을 의미하도록 전처리를 진행한다.
1.4 재생 시간 만큼 문자열을 반복하여 재생 문자열을 생성한다.
1.5 배열에 재생시간, 노래이름, 재생 문자열을 저장한다.
2. 배열에서 문자열 m이 포함 된 재생 문자열이 있다면,
2.1 만약 정답이 존재한다면, 재생시간을 비교하여 정답에 저장한다.
2.2 만약 정이 존재하지 않다면, 바로 정답에 저장한다.
- 문자열 분리 함수
vector<string> get_string_arr(string str) {
string tmp = "";
vector<string> ans;
for (auto it : str) {
if (it == ',') {
ans.push_back(tmp);
tmp = "";
}
else
tmp += it;
}
ans.push_back(tmp);
return ans;
}
- 재생 시간을 계산 하는 함수
int get_minute(string start, string end) {
int start_h = stoi(start.substr(0, 2));
int start_m = stoi(start.substr(3, 2));
int end_h = stoi(end.substr(0, 2));
int end_m = stoi(end.substr(3, 2));
int sum_start = start_h * 60 + start_m;
int sum_end = end_h * 60 + end_m;
return sum_end - sum_start;
}
- 다음은 문자열을 전처리하는 함수이다.
string get_hash_num(string str) {
string hash[12] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
string tmp;
int index;
if (str[1] == '#') {
tmp = str.substr(0, 2);
index = 2;
}
else {
tmp = str.substr(0, 1);
index = 1;
}
string hash_arr = "";
while (index < str.size()) {
if (str[index] == '#') {
tmp += str[index];
}
else {
for (int j = 0; j < 12; j++) {
if (hash[j] == tmp) {
if (j == 10) {
hash_arr += 'A';
}
else if (j == 11) {
hash_arr += 'B';
}
else
hash_arr += to_string(j);
break;
}
}
tmp = str[index];
}
index++;
}
for (int j = 0; j < 12; j++) {
if (hash[j] == tmp) {
if (j == 10) {
hash_arr += 'A';
}
else if (j == 11) {
hash_arr += 'B';
}
else
hash_arr += to_string(j);
break;
}
}
return hash_arr;
}
- 다음은 전체 코드이다.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
vector<string> get_string_arr(string str) {
string tmp = "";
vector<string> ans;
for (auto it : str) {
if (it == ',') {
ans.push_back(tmp);
tmp = "";
}
else
tmp += it;
}
ans.push_back(tmp);
return ans;
}
int get_minute(string start, string end) {
int start_h = stoi(start.substr(0, 2));
int start_m = stoi(start.substr(3, 2));
int end_h = stoi(end.substr(0, 2));
int end_m = stoi(end.substr(3, 2));
int sum_start = start_h * 60 + start_m;
int sum_end = end_h * 60 + end_m;
return sum_end - sum_start;
}
string get_hash_num(string str) {
string hash[12] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
string tmp;
int index;
if (str[1] == '#') {
tmp = str.substr(0, 2);
index = 2;
}
else {
tmp = str.substr(0, 1);
index = 1;
}
string hash_arr = "";
while (index < str.size()) {
if (str[index] == '#') {
tmp += str[index];
}
else {
for (int j = 0; j < 12; j++) {
if (hash[j] == tmp) {
if (j == 10) {
hash_arr += 'A';
}
else if (j == 11) {
hash_arr += 'B';
}
else
hash_arr += to_string(j);
break;
}
}
tmp = str[index];
}
index++;
}
for (int j = 0; j < 12; j++) {
if (hash[j] == tmp) {
if (j == 10) {
hash_arr += 'A';
}
else if (j == 11) {
hash_arr += 'B';
}
else
hash_arr += to_string(j);
break;
}
}
return hash_arr;
}
string solution(string m, vector<string> musicinfos) {
string answer = "(None)";
vector<pair<int, pair<string, string>>> dic;
for (auto it : musicinfos) {
vector<string> infos = get_string_arr(it);
int play_time = get_minute(infos[0], infos[1]);
string music_arr = "";
string info = get_hash_num(infos[3]);
for (int i = 0; i < (play_time / info.size()); i++) {
music_arr += info;
}
music_arr += info.substr(0, (play_time % info.size()));
dic.push_back(make_pair(play_time, make_pair(infos[2], music_arr)));
}
string hash_m = get_hash_num(m);
int time = 0;
for (auto it : dic) {
if (it.second.second.find(hash_m) != string::npos && time < it.second.second.size()) {
answer = it.second.first;
time = it.second.second.size();
}
}
if (answer.empty())
answer = "(None)";
return answer;
}
3. 결어
문자열 전처리를 부분이 어려웠지만, 나름 적당한 난이도의 구현 문제라고 생각한다. 중요한점은 이런 문제를 40분 안에 다 풀어야 한다는 것... 구현 문제를 더 풀어봐야할 것 같다.