안녕하시오 !
이 문제는 구현이다. 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개인데, #이 붙은 문자는 앞 글자와 함께 하나의 음절로 묶어야 한다.
#구분
vector<string> hashcontrol(const string& a) {
vector<string> music_song;
for (int i = 0; i < a.size(); i++) {
if (i + 1 < a.size() && a[i + 1] == '#') {
music_song.push_back(string(1, a[i]) + "#");
i++;
} else {
music_song.push_back(string(1, a[i]));
}
}
return music_song;
}
이때 새롭게 알게된 함수가 있다. 바로 char를 string으로 변환하는 함수이다.
string(size_t n, char c);
n: 문자의 반복 횟수
c: 반복할 문자
즉, string(3, 'A') → "AAA"
보통은 같은 문자를 n번 반복하는 문자열을 만들고 싶을 때 사용하는 생성자이다.
C++에서 char를 바로 string으로 변환하는 표준 함수는 없다. 따라서 string 생성자를 이용해 위와 같이 char를 string으로 변환할 수 있다.
char c = 'C';
string(1, c); // 'C' 문자를 1번 반복한 문자열 → "C"
char 하나를 string으로 감싸는 간단한 방법이다.
음악이 몇분간 재생됐는지를 반환하는 함수도 만들었다.
int getTime(const string& start, const string& end) {
int sh = stoi(start.substr(0, 2));
int sm = stoi(start.substr(3, 2));
int eh = stoi(end.substr(0, 2));
int em = stoi(end.substr(3, 2));
return (eh * 60 + em) - (sh * 60 + sm);
음악은 반복재생 되므로 재생된 시간이 악보길이보다 길 경우 반복재생된 전체 음을 fullMusic에 저장했다.
for (int t = 0; t < playTime; t++) {
fullMusic.push_back(parsedSheet[t % parsedSheet.size()]);
}
그러고 난 후, 네오가 기억한 멜로디가 포함된 음악을 찾아내는 함수를 작성했다.
bool isMatch(const vector<string>& full, const vector<string>& pattern) {
if (pattern.size() > full.size()) return false;
for (int i = 0; i <= full.size() - pattern.size(); i++) {
bool match = true;
for (int j = 0; j < pattern.size(); j++) {
if (full[i + j] != pattern[j]) {
match = false;
break;
}
}
if (match) return true;
}
return false;
}
전체 코드를 보면 흐름을 이해하기 더 쉬울 것이다.
코드 전문은 다음과 같다.
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
// # 구분
vector<string> hashcontrol(const string& a) {
vector<string> music_song;
for (int i = 0; i < a.size(); i++) {
if (i + 1 < a.size() && a[i + 1] == '#') {
music_song.push_back(string(1, a[i]) + "#");
i++;
} else {
music_song.push_back(string(1, a[i]));
}
}
return music_song;
}
bool isMatch(const vector<string>& full, const vector<string>& pattern) {
if (pattern.size() > full.size()) return false;
for (int i = 0; i <= full.size() - pattern.size(); i++) {
bool match = true;
for (int j = 0; j < pattern.size(); j++) {
if (full[i + j] != pattern[j]) {
match = false;
break;
}
}
if (match) return true;
}
return false;
}
int getTime(const string& start, const string& end) {
int sh = stoi(start.substr(0, 2));
int sm = stoi(start.substr(3, 2));
int eh = stoi(end.substr(0, 2));
int em = stoi(end.substr(3, 2));
return (eh * 60 + em) - (sh * 60 + sm);
}
string solution(string m, vector<string> musicinfos) {
string answer = "(None)";
int max_time = -1;
vector<string> target = hashcontrol(m);
for (int i = 0; i < musicinfos.size(); i++) {
stringstream ss(musicinfos[i]);
string start, end, title, sheet;
getline(ss, start, ',');
getline(ss, end, ',');
getline(ss, title, ',');
getline(ss, sheet, ',');
int playTime = getTime(start, end);
vector<string> parsedSheet = hashcontrol(sheet);
vector<string> fullMusic;
for (int t = 0; t < playTime; t++) {
fullMusic.push_back(parsedSheet[t % parsedSheet.size()]);
}
if (isMatch(fullMusic, target)) {
if (playTime > max_time) {
max_time = playTime;
answer = title;
}
}
}
return answer;
}