프로그래머스/2레벨

[1차] 뉴스 클러스터링/C++

Koalitsiya 2023. 1. 12. 15:18
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

풀이방법

두 문자열을 문제에 나와있는 조건에 맞춰 각각 두 글자씩 잘라서 벡터에 담고 서로 비교하며 교집합의 수를 구한 뒤 합집합의 수를 구하고 두 수를 통해 자카드 유사도를 구했다.

 

1. 대문자와 소문자의 차이는 무시한다 되어있으므로 두 문자열을 소문자로 변환해준다.

2. 두 글자가 전부 영문자인지 확인하고 맞다면 문자열에서 두 글자를 잘라 벡터에 담는다.

3. 이후 다중집합을 의미하는 벡터 2개가 다 비어있다면 65536을 리턴한다.

4. 아니라면 두 벡터의 원소를 비교하며 값이 같으면 교집합의 수를 하나 더하고 해당 원소의 값을 빈 문자열로 바꿔 교집합이 중복으로 검출되지 않도록한다.

5. 위를 통해 구한 교집합의 수로 합집합의 수도 구하고 합집합의 수가 0이면 나눌 수 없으므로 65536 리턴, 아니라면 자카드 유사도를 구한 뒤 65536을 곱한 값을 리턴한다.

 

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

int solution(string str1, string str2) {
    vector<string> multiset1;
    vector<string> multiset2;
    int intersectionCount = 0;
    int unionCount = 0;
    
    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++) {
        if(isalpha(str1[i]) && isalpha(str1[i+1]))
            multiset1.push_back(str1.substr(i,2));
    }
    
    for(int i = 0; i < str2.length() - 1; i++) {
        if(isalpha(str2[i]) && isalpha(str2[i+1]))
            multiset2.push_back(str2.substr(i,2));
    }
    
    if(multiset1.empty() && multiset2.empty())
        return 65536;
    
    for(int i = 0; i < multiset1.size(); i++) {
        for(int j = 0; j < multiset2.size(); j++) {
            if(multiset1[i] == multiset2[j]) {
                intersectionCount++;
                
                multiset2[j] = "";
                
                break;
            }
        }
    }
    
    unionCount = multiset1.size() + multiset2.size() - intersectionCount;
    
    if(unionCount == 0) return 65536;
    
    double jaccard = (double)intersectionCount / (double)unionCount;
    
    return jaccard*65536;
}

코드블럭에 언어를 지정할 수 있단 걸 이제야 알았다