본문 바로가기
프로그래머스

프로그래머스 [1차] 뉴스클러스터링(2018 KAKAO BLINED RECRUITMENT)

by 콩순이냉장고 2020. 9. 9.

문제 URL : https://programmers.co.kr/learn/courses/30/lessons/17677

 

코딩테스트 연습 - [1차] 뉴스 클러스터링

뉴스 클러스터링 여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다. Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브��

programmers.co.kr

문제 접근법 :

 

클러스터 문자열만들기

조건1 사이즈가 2인 문자열을 잘라서 소문자 혹은 대문자형식으로 된 문자열을 만들어줍니다.

조건2 만든 문자열의 소문자 대문자 구분을 없애야합니다. ->

 

접근1 : 문자열 0~size까지  2개씩 자릅니다. ->조건(마지막 사이즈가 2가 아닐경우)

접근2 : 대소문자 구분을 없애기위해 전부 소문자로 바꿨습니다. (이두가지가 만족하면 클러스터형 문자열)

접근3 : 클러스터형 문자열이 만들어지면 map을 이용하여 집합을 표현합니다. 여기서 만들어진 집합을 set1,set2라고 하겠습니다. 그리고 해당 문자열의 카운트 개수를 증가시켜줍니다. (전 unordered map을 사용했습니다. 이게 map보다 빠릅니다.)

접근4 : set1과 set2의 합집합과 차집합을 만듭니다.

 

소스코드 : 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//By 콩순이냉장고
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <unordered_map>
using namespace std;
bool isalpha(char c){//알파벳인지 확인
    if ('a' <= c&&<= 'z')
        return true;
    return false;
}
bool iscluster(string &s)//클러스터형인지 동시에 소문자로도 바꿈
{
    if (s.size() != 2)
        return false;
    s[0= tolower(s[0]); //소문자로바꾸기
    s[1= tolower(s[1]);
    if (isalpha(s[0]) && isalpha(s[1]))
        return true;
    return false;
}
void makeUniok(unordered_map<stringint> &set1, unordered_map<stringint> &set2, unordered_map<stringint> &Union){//합집합
    for (auto it = set1.begin(); it != set1.end(); it++)
    {
        if (Union.count(it->first) == 0){
            int cnt1 = it->second;
            int cnt2 = 0;
            if (set2.count(it->first))
                cnt2 = set2[it->first];
            Union[it->first] = max(cnt1, cnt2);
        }
    }
}
void makeInter(unordered_map<stringint> &set1, unordered_map<stringint> &set2, unordered_map<stringint> &inter){//차집합
    for (auto it = set1.begin(); it != set1.end(); it++)
    {
        if (inter.count(it->first) == 0){
            int cnt1 = it->second;
            if (set2.count(it->first)){//둘다 존재해야함
                int cnt2 = set2[it->first];
                inter[it->first] = min(cnt1, cnt2);
            }
        }
    }
}
int Count(unordered_map<stringint> &set1)//해당 원소개수들 구하기
{
    int sum = 0;
    for (auto it = set1.begin(); it != set1.end(); it++)
    {
        sum += it->second;
    }
    return sum;
}
int solution(string str1, string str2) {
    int answer = 0;
    unordered_map<stringint> set1, set2, Union, Inter;
    for (int i = 0; i < str1.size(); i++)
    {
        string s = str1.substr(i, 2);//2개씩자르기
        if (iscluster(s)){
            set1[s]++;
        }
 
    }
    for (int i = 0; i < str2.size(); i++)
    {
        string s = str2.substr(i, 2);
        if (iscluster(s))
            set2[s]++;
    }
    makeUniok(set1, set2, Union);
    makeUniok(set2, set1, Union);
    makeInter(set1, set2, Inter);
    makeInter(set2, set1, Inter);
    double sum1 = Count(Union);
    double sum2 = Count(Inter);
 
    if (sum1 == 0 && sum2 == 0)//공집합일경우
        return 65536;
    return (sum2 / sum1) * 65536;
}
 
 
 
 
cs

 

모르는것 혹은 궁금한점이 혹은 논리가 잘못된것이 있다면 언제든지 댓글을 이용해주시길 부탁드립니다.