[프로그래머스][1차] 뉴스 클러스터링

gcoco·2023년 5월 5일
0

안녕하세요! 치킨을 먹어 기분이 좋은 GCOCO입니다!🍗🍖🥠

BHC의 맛초킹으로다가, 치즈볼과 함께 가족과 맛있게 먹었더니 엔돌핀이 솟는 기분입니다 wwww우효
기분좋은 시작과 함께, 후식으로 쿠키부터 먹어볼까요?


잡설 한 COOKIE🍪

저번 포스팅에서 말하지 않은, 선배님이 강조해주신 한 가지 더 중요한 포인트를 말씀드리고자 합니다!
그것은 바로 '같이 일하고 싶은 사람'이 되자는 것입니다!

생각해보면 정말로 그렇습니다. 저도 삶을 살아오면서 어떤 주제가 되었건 간에 누군가와는 함께 해보고 싶다라는
생각이 들기도 하였고, 저 사람만은 피하고 싶다, 같이 하고싶지 않다라는 생각이 드는 때도 있었습니다.

하물며 신입사원을 뽑는것은 직장에서 같이 일을 하고 싶은 사람을 뽑는것인데 당연히 일도 잘하고 긍정적인 의사소통이 잘 이루어지는 동료와 일하고 싶다고 생각합니다! 저도 그렇다고 생각합니다.

그러면 여기서 질문이 한 가지 나올것 같습니다.

예상하는바는

'그렇다면 너의 직장 동료, 상사, 피할수 없는 상대와의 갈등, 문제가 생기면 넌 어떻게 대처할 것이냐!'

캬. 아주 좋은 질문입니다. 훌륭한 예측인것 같습니다.

이에 대한 저의 대답은 다음 포스팅에서 다뤄보도록 하겠습니다!😙


문제링크:

이 문제는, 자카드 유사도라는것을 사용하여 두 문자열을 검사하는 문제입니다!
저도 자카드 유사도라는 것을 이번 문제에서 처음 접해봤습니다만 주어진 기준에 따라 작성한다면
어렵지 않게 작성하실 수 있을것이라 생각합니다!

저의 코드는 다음과 같습니다.

#include <string>
#include <unordered_map>
#include <algorithm>

using namespace std;

int solution(string str1, string str2) {
    int answer = 0;
    const double factor = 65536;
    
    unordered_map<string,double> um1;//다중집합용 unordered_map
    unordered_map<string,double> um2;
    transform(str1.begin(),str1.end(),str1.begin(),::tolower);//알파벳을 소문자화
    transform(str2.begin(),str2.end(),str2.begin(),::tolower);
    
    //두글자씩 끊어서 다중집합을 만들자.
    for(int i=0;i<str1.length()-1;i++){
        string tmp ="";
        //str1의 연속된 두 글자가 알파벳이라면 다중집합에 추가
        if(isalpha(str1[i])&&isalpha(str1[i+1])){
            tmp.push_back(str1[i]);
            tmp.push_back(str1[i+1]);
            um1[tmp]++;
        }
    }
    
    for(int i=0;i<str2.length()-1;i++){
        string tmp ="";
        //str2의 연속된 두 글자가 알파벳이라면 다중집합에 추가
        if(isalpha(str2[i])&&isalpha(str2[i+1])){
            tmp.push_back(str2[i]);
            tmp.push_back(str2[i+1]);
            um2[tmp]++;
        }
    }
    
    //앗! 다중집합이 없다!! 종료!!
    if(um1.empty()&&um2.empty())
        return 65536;
    
    //합집합과 교집합의 수를 세보자
    double hap,gyo;
    hap=gyo=0;
    
    //um1 집합을 순회하며
    for(auto i:um1){
    	//합집합은 더 큰 값을 더해주고
        hap+=max(i.second,um2[i.first]);
        //um2 집합에도 있는 원소인지 체크 후
        if(um2[i.first]!=0){
			//작은값을 교집합에 더해주기
            gyo+=min(i.second,um2[i.first]);
        }
    }
    
    //um2 집합을 순회하며
    for(auto i:um2){
    	//hap집합에 추가되지 않은 원소들을 찾아 더해주기
        if(um1[i.first]==0){
            hap+=i.second;
        }
    }
    //자카드 유사도 계산
    answer= gyo/hap*factor;
    
    return answer;
}

요정도입니다!

두 개의 포인트를 보도록 하겠습니다.

<unordered_map>의 이용 이유 : <map>템플릿은 내부적으로 정렬이 이루어지기 때문에 <unordered_map> 보다 느립니다. 얼마나 느리냐구요? 그건 나중의 STL 사용법 포스팅을 다룰때 이야기 하도록 하겠습니다!
아무쪼록, A,B 집합 생성을 위해 사용했다고 생각해주시면 되겠습니다.

transform(str1.begin(),str1.end(),str1.begin(),::tolower);//알파벳을 소문자화
transform(str2.begin(),str2.end(),str2.begin(),::tolower);

이 부분은 정말로 꿀팁이라고 말씀드릴 수 있겠습니다. <algorithm> header의 transform이란 함수를 사용하게 되면, 위와 같은 형태를 이용해 쉽게 알파벳을 소문자화 할 수 있습니다! 알아두시면 편리하리라 생각합니다.


결국 이 문제는 다음의 과정이었습니다.

  1. 집합 A,B를 생성을 하고
  2. 그 두 개의 집합의 교집합과 합집합을 추출해서
  3. 65536을 곱해서 return 하여라!

도움이 되셨으면, 다행입니다!

profile
그코코 입니다.

0개의 댓글