[프로그래머스] [1차] 뉴스 클러스터링 (문제 설명, 해결 과정, 코드 전문, c++)
문제 설명 |
본 문제는 프로그래머스의 [1차] 뉴스 클러스터링 문제입니다.
해결 과정 |
입력형식에서 볼 수 있듯 대소문자에 대한 구분을 하지 않습니다. 모든 알파벳을 소문자로 바꾸고
각 문자열에서 앞 뒤 모두 알파벳인 경우를 추출해 배열에 담습니다.
이후 합집합과 교집합의 수를 구해야하는데 합집합은 두 배열의 사이즈의 합에서 교집합의 수 만큼 뺸 것이니
교집합만을 구하면 됩니다. 교집합을 구하기 위해 두 배열 중 하나가 다 탐색될 때까지 순회합니다.
이 과정에서 중복을 허용해야하기 때문에 한 번 접근했던 부분은 visited 배열을 두어 똑같은 위치에 대한 중복을 방지합니다. 그리고 이 과정이 끝나고 나면 출력 형식에 맞춰 연산하고 반환합니다.
코드 전문 |
#include <string>
#include <vector>
#include <cctype>
#include <algorithm>
using namespace std;
void parser_alpha_lower(string& str)
{
for (char& ch : str)
if (ch >= 'A' && ch <= 'Z') ch += ('a' - 'A');
}
vector<string> get_parser_vec(string &str)
{
vector<string> v;
string t_str{ "" };
for (int i = 0; i < str.size() - 1; i++)
{
if (isalpha(str[i]) == 1024 && isalpha(str[i+1]) == 1024) // isalpha는 컴파일러마다 반환값 달라 대문자1 소문자2 반환, 대소문자 구분 없이 1024반환
{
t_str += str[i]; t_str += str[i+1];
v.emplace_back(t_str);
t_str.clear();
}
}
return v;
}
int solution(string str1, string str2) {
int answer = 0;
vector<string> v1;
vector<string> v2;
parser_alpha_lower(str1);
parser_alpha_lower(str2);
//transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
//transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
v1 = get_parser_vec(str1);
v2 = get_parser_vec(str2);
int sum_size = 0;
int prod_size = 0;
vector<int> visited(v2.size(), 0);
for (int i = 0; i < v1.size(); i++)
{
for (int j = 0; j < v2.size(); j++)
{
if (visited[j] == 1) continue;
if (v1[i] == v2[j])
{
visited[j] = 1;
prod_size++;
break;
}
}
}
sum_size = v1.size() + v2.size() - prod_size;
if (prod_size == 0 && sum_size == 0) return 65536;
answer = (int)(65536 * ((double)prod_size / (double)sum_size));
// return sum_size ? 65536 * prod_size / sum_size : 65536;
return answer;
}
느낀 점 (잡설 99% , 배운점 1%(많은 편)) |
중복이란 말에 multiset, map을 사용하여 만들다가 코드가 너무 복잡해져 그만뒀습니다. set, map의 key로 string을 넘길 때 rvalue만 넣으라고 뜨는데 lvalue는 왜 못 넣는건가 의문이 들었네요. template argument deduction 으로 좀 알아봐도 감이 안 잡히네요. 요번에 범한 실수는 string에서 추출한 문자들을 string의 + 연산과 햇갈려 그냥 더하기 연산을 시킨 것이 인상 적입니다. cctype의 isalpha 함수는 컴파일러에 따라 반환값이 달랐습니다. vsstudio에서는 nonalpha : 0, 대문자 : 1, 소문자 : 2, clang에서는 nonalpha : 0, 대소문자 :1024이었습니다.
이번 문제를 풀며 기억에 남는건 중복을 위해 visited 배열을 사용하였던 것 그리고 문제의 키워드에 너무 빠져 코드를 복잡하게 만들지 않을 것.
긴 글 읽어주셔서 감사합니다.
부족한 점이 있다면 부디 알려주시면 감사하겠습니다.