Programmers_뉴스 클러스터링

문제의 풀이보다는 문제를 어떻게 더 단순하게 만들까에 대해서 더 고민한 문제.

  • 문자열을 2자씩 끊어서 두 문자열의 합집합과 교집합을 구하는 문제.
  • 문자열에서 문자만 유효하고, 대소문자를 구분하지 않기에 첫 문장에서 transform 함수를 사용해 문자열을 모두 소문자로 바꿔준다.
    • transform(str1.begin(), str1.end(), str1.begin(), ::tolower) : 문자열 str1을 모두 소문자로 바꿔주는 함수.
    • 배웠다. 또 배웠다.
  • for문에서 문자인 것만 vector에 넣어준다.
  • 두 비교 대상이 모두 공집합인 경우, 65536 을 return 한다는 점을 잊으면 안된다.
  • 필자는 두 문자열의 교집합과 합집합을 구할때, 합집합 = 두 집합을 모두 더한 수 - 교집합 의 원리를 사용했다.
  • 그래서 교집합만 구해줬는데, check 함수를 통해서 중복되는 부분의 개수를 세줬다.

💻전체코드

#include <string>
#include <vector>
#include <string.h>
#include <algorithm>

using namespace std;

bool check[2001];

int solution(string str1, string str2)
{
    int answer = 0;

    vector<string> v[2];

    transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
    transform(str2.begin(), str2.end(), str2.begin(), ::tolower);

    for (int i = 0; i < str1.size() - 1; i++)
    {
        if (str1[i] >= 'a' && 'z' >= str1[i] && 'a' <= str1[i + 1] && str1[i + 1] <= 'z')
            v[0].push_back(str1.substr(i, 2));
    }

    for (int i = 0; i < str2.size() - 1; i++)
    {
        if (str2[i] >= 'a' && 'z' >= str2[i] && 'a' <= str2[i + 1] && str2[i + 1] <= 'z')
            v[1].push_back(str2.substr(i, 2));
    }

    if (v[0].empty() && v[1].empty())
        return 65536;

    int uni = 0, intersection = 0;

    for (int i = 0; i < v[0].size(); i++)
    {
        for (int j = 0; j < v[1].size(); j++)
        {
            if (check[j])
                continue;
            if (v[0][i] == v[1][j])
            {
                check[j] = 1;
                intersection++;
                break;
            }
        }
    }
    uni = v[0].size() + v[1].size() - intersection;

    if (uni == 0)
        return 65536;

    double tmp = (double)intersection / (double)uni;

    answer = tmp * 65536;

    return answer;
}

좋은 웹페이지 즐겨찾기