알고리즘/프로그래머스
프로그래머스 - 2018 KAKAO BLIND RECRUITMENT [1차] 뉴스 클러스터링
시나모온
2020. 4. 28. 02:36
문제 링크입니다 : https://programmers.co.kr/learn/courses/30/lessons/17677
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
인풋으로 들어온 데이터를 먼저 소문자로 다 변환해줬습니다.
그 후, 순서는 없고 개수는 세는 데이터 구조를 만들기 위해서 map을 사용했습니다.
데이터를 돌면서 map을 완성하고
마지막에 합집합과 차지합을 구할 때, C++ map 자료구조의 특성을 이용했습니다. map은 내부적으로 완전 이진트리 형태를 갖추고 있어서 iterator로 차례대로 순회하면 자동으로 정렬된 순서대로 탐색할 수 있습니다.
두 데이터 셋의 값을 비교를 통해서 합집합과 차집합을 구하면 되기 때문에, 병합정렬에서 merge 할 때처럼 포인터를 두 개 두어서 병합을 좀 더 빠르게 했습니다. 그래서 전체 시간 복잡도 O(N)으로 풀 수 있었습니다.
#include <string>
#include <map>
#include <algorithm>
#include <cctype>
#include <iostream>
using namespace std;
int solution(string str1, string str2) {
int answer = 0;
transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
map<string, int> m1;
map<string, int> m2;
map<string, int>::iterator iter1;
map<string, int>::iterator iter2;
for(int i = 0; i < str1.size() - 1; i++) {
if(!isalpha(str1[i]) || !isalpha(str1[i + 1])) continue;
string twoChar = "";
twoChar += str1[i];
twoChar += str1[i + 1];
if(m1.find(twoChar) == m1.end()) {
m1[twoChar] = 1;
} else {
m1[twoChar]++;
}
}
for(int i = 0; i < str2.size() - 1; i++) {
if(!isalpha(str2[i]) || !isalpha(str2[i + 1])) continue;
string twoChar = "";
twoChar += str2[i];
twoChar += str2[i + 1];
if(m2.find(twoChar) == m2.end()) {
m2[twoChar] = 1;
} else {
m2[twoChar]++;
}
}
// 병합 정렬 합칠 때는 아이디어, 시간 복잡도가 무려 O(1)이다.
iter1 = m1.begin(), iter2 = m2.begin();
int sum1 = 0;
int sum2 = 0;
while(iter1 != m1.end() && iter2 != m2.end()) {
if(iter1->first > iter2->first) {
//합집합으로 가버렷!
sum2 += iter2->second;
iter2++;
} else if(iter1->first < iter2->first) {
//합집합으로 가버렷!
sum2 += iter1->second;
iter1++;
} else {
//교집합
sum1 += min(iter1->second, iter2->second);
sum2 += max(iter1->second, iter2->second);
iter1++;
iter2++;
}
}
while(iter1 != m1.end()) {
//m1에 남은 값들이 m2의 마지막 값보다 더 크다.
sum2 += iter1->second;
iter1++;
}
while(iter2 != m2.end()) {
sum2 += iter2->second;
iter2++;
}
if(sum1 == 0 && sum2 == 0) answer = 65536;
else {
answer = ((double)sum1 / (double)sum2) * 65536;
}
return answer;
}

개발 환경 : vscode
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~