문제 설명
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.
속한 노래가 많이 재생된 장르를 먼저 수록합니다.
장르 내에서 많이 재생된 노래를 먼저 수록합니다.
장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.
장르의 정보를 담은 Genre구조체를 생성한 후,
struct Genre {
int totalPlayed=0;
int mostPlayedAmount=0;
int secondMostPlayedAmount=0;
int mostPlayedNum=0;
int secondMostPlayedNum=0;
};
생성될때 내부값들을 다 0으로 초기화해줬다.
장르 이름과 장르 구조체를 매핑하는 map을 하나 선언하고,
각 장르의 totalPlayed와 장르 구조체를 매핑하는 map을 또 하나 선언했다.
두번째 map은 장르구조체를 각 장르의 totalPlayed값의 내림차순으로 정렬을 해야하는데 비교함수 구현하기 귀찮아서 map을 이용했다.
map<string, Genre> MostPlayed;
map<int, Genre, greater<int>> SortGenre;
어차피 genre벡터와 play벡터의 원소수는 같으므로 순회하며
각 장르의 totalplayed에 더해주고,
mostPlayedAmount, secondMostPlayedAmount를 갱신한다.
for (int i = 0; i < genres.size(); i++) {
MostPlayed[genres[i]].totalPlayed += plays[i];
if (MostPlayed[genres[i]].mostPlayedAmount < plays[i]) {
//첫곡 갱신전에 바꿔줘야함
MostPlayed[genres[i]].secondMostPlayedAmount = MostPlayed[genres[i]].mostPlayedAmount;
MostPlayed[genres[i]].secondMostPlayedNum= MostPlayed[genres[i]].mostPlayedNum;
MostPlayed[genres[i]].mostPlayedAmount = plays[i];
MostPlayed[genres[i]].mostPlayedNum = i;
}
else if (MostPlayed[genres[i]].secondMostPlayedAmount<plays[i] && MostPlayed[genres[i]].mostPlayedAmount >= plays[i]) {
MostPlayed[genres[i]].secondMostPlayedAmount = plays[i];
MostPlayed[genres[i]].secondMostPlayedNum = i;
}
}
중요한건 첫번째로 많이들은 곡이 갱신될 때, 두번째곡 정보를 첫번째로 많이 들은 곡정보로 갱신해야한다!!!
map은 algorithm헤더의 sort함수와는 다르게
디폴트 비교함수가 less이므로 greater을 달아줘야 내림차순으로 정렬된다.
SortGenre에 MostPlayed맵을 넣어주면서 totalPlayed변수에 맞게 정렬되도록 한다.
for (auto iter = MostPlayed.begin(); iter != MostPlayed.end(); ++iter) {
SortGenre[(*iter).second.totalPlayed] = (*iter).second;
}
그 후, totalPlayed숫자를 기준으로 내림차순으로 정렬된 SortGenre맵을 순회하며 각 Genre구조체의 첫번째로 많이들은 숫자와 두번째로 많이들은 숫자를 답 벡터에 집어넣는다.
for (auto iter = SortGenre.begin(); iter != SortGenre.end(); ++iter) {
answer.push_back((*iter).second.mostPlayedNum);
//한개일수도있음
if((*iter).second.secondMostPlayedAmount!=0)
answer.push_back((*iter).second.secondMostPlayedNum);
}
주의할점은 각 장르의 수록곡이 하나일수도있따!!!!!
조심해야한다.
#include <string>
#include <vector>
#include<map>
using namespace std;
struct Genre {
int totalPlayed=0;
int mostPlayedAmount=0;
int secondMostPlayedAmount=0;
int mostPlayedNum=0;
int secondMostPlayedNum=0;
};
vector<int> solution(vector<string> genres, vector<int> plays) {
vector<int> answer;
map<string, Genre> MostPlayed;
map<int, Genre, greater<int>> SortGenre;
for (int i = 0; i < genres.size(); i++) {
MostPlayed[genres[i]].totalPlayed += plays[i];
if (MostPlayed[genres[i]].mostPlayedAmount < plays[i]) {
//첫곡 갱신전에 바꿔줘야함
MostPlayed[genres[i]].secondMostPlayedAmount = MostPlayed[genres[i]].mostPlayedAmount;
MostPlayed[genres[i]].secondMostPlayedNum= MostPlayed[genres[i]].mostPlayedNum;
MostPlayed[genres[i]].mostPlayedAmount = plays[i];
MostPlayed[genres[i]].mostPlayedNum = i;
}
else if (MostPlayed[genres[i]].secondMostPlayedAmount<plays[i] && MostPlayed[genres[i]].mostPlayedAmount >= plays[i]) {
MostPlayed[genres[i]].secondMostPlayedAmount = plays[i];
MostPlayed[genres[i]].secondMostPlayedNum = i;
}
}
for (auto iter = MostPlayed.begin(); iter != MostPlayed.end(); ++iter) {
SortGenre[(*iter).second.totalPlayed] = (*iter).second;
}
for (auto iter = SortGenre.begin(); iter != SortGenre.end(); ++iter) {
answer.push_back((*iter).second.mostPlayedNum);
//한개일수도있음
if((*iter).second.secondMostPlayedAmount!=0)
answer.push_back((*iter).second.secondMostPlayedNum);
}
return answer;
}
함정이라기엔 뭐하지만 내가 실수한 부분들이 좀 많은 문제다.
다음에 다시 체크하려고 한번에 못푼문제 태그를 달았다.
첫번째 실수는 각 장르의 수록곡이 하나일수도 있다는것이고,
두번째 실수는 제일 많이들은 곡이 갱신될때 현재 제일 많이들은 곡을 두번째 제일많이 들은곡으로 갱신해줘야한다.
세번째 실수는 등호를 빼먹어서 제일 많이들은 곡과 같은 값이 input값으로 들어왔을때, 두번째 많이들은 곡으로 넣어야하는데
else if (MostPlayed[genres[i]].secondMostPlayedAmount<plays[i] &&
MostPlayed[genres[i]].mostPlayedAmount >= plays[i]) {
plays[i]왼쪽에 =을 빼먹어서 제일 많이들은곡과 같은 값이 들어오면
무시되었다..