프로그래머스의 [1차] 뉴스 클러스터링 (Lv2) 문제이다.
[ 문제풀이 ]
입력으로 주어지는 2개의 문자열을, 2개 단위로 짤라서 저장했을 때, 교집합의 갯수와 합집합의 갯수를 구해야 하는 문제이다.
주어진 문자열들을 어떻게 관리했는지부터 정답을 도출하는 과정까지 다음과 같은 예시를 가지고 진행해보자.
string str1 = "aa1+bc2"
string str2 = "ABcAaa12"
위의 2가지 문자열을 가지고 진행해보자.
#1. 올바른 문자열 추출하기
가장먼저, 주어진 문자열을 앞에서부터 2개씩 짤라서, 올바른 문자열인지 판단해 주었다.
문제에서 제시한대로, 영문자로 된 글자 쌍만 유효하기 때문에, 유효한 문자열이 판단해 주는 것을 가장 먼저 진행해 주었다.
또한, 대소문자 구분이 없다고 했기 때문에, 모두 소문자로 통일해 주었다.
str1과 str2에 대한 올바른 문자열만 적어보면..
str1 = [ "aa" , "bc" ]
str2 = [ "ab" , "bc" , "ca" , "aa", "aa" ]
가 된다.
지금부터는 위와같이, 문제에 조건에 어긋나지 않는, 영문자 글자 쌍으로만 이루어진 문자열들을 "올바른 문자열" 이라고 표현하겠다.
#2. map<string, int> 를 이용한 문자열 관리
간단하게 map에 대해서 알아보자. (map에 대해서 잘 아시는 분들은 #2-1 로 넘어가셔도 좋습니다.)
STL #include<map> 을 선언하면, map이라는 자료구조를 사용할 수 있다.
map은 'key'값이라고 불리는 고유값과, 'value'라고 불리는 해당 고유값이 갖는 값 2개를 쌍으로 관리하는 자료구조이다.
본인이 이 문제에서 선언한 map<string, int> 는, 문자열 'string'을 key값이라고 불리는 고유값으로 사용하고, 해당 string이 가지고 있는 값을 int로 표현하겠다 라고 했는데, 이렇게 선언한 이유는, "해당 문자열이 str1과 str2에 존재하는 갯수를 파악" 하기 위해서이다. 예를 들어서 map<string , int> MAP 이렇게 선언해놓고, MAP["ABC"] = 1 이라고 설정을 하게 되면, 이게 의미하는 것은 "현재 MAP에서 "ABC"라는 key값을 가진 놈이 가지고 있는 값은 '1'입니다." 를 의미한다.
#2-1 map<string, int> 를 이용한 올바른 문자열 갯수 관리
우리가 최종적으로 구해야 하는 값은, str1과 str2에서 발생할 수 있는 올바른 문자열들 중에서, 교집합에 속하는 문자열의 갯수와, 합집합에 속하는 문자열의 갯수를 구해야 한다.
그래서, 본인은 map을 이용해서, str1에서 발생할 수 있는 문자열들의 갯수와 str2에서 발생할 수 있는 문자열들의 갯수를 파악해 주었다.
str1 = { "aa" , "bc" }
str2 = { "ab", "bc", "ca", "aa", "aa" } 가 되는데,
str1의 map에서는 str1_map["aa"] = 1 , str1_map["bc"] = 1이 될 것이고,
str2의 map에서는 str2_map["ab"] = 1 , str2_map["bc"] = 1, str2_map["ca"] = 1 , str2_map["aa"] = 2 가 될 것이다.
위의 숫자들을보면, 각각의 문자열에서 발생할 수 있는 올바른 문자열들과, 그 갯수들을 저장하고 있음을 알 수 있다.
#3. 전체 문자열을 따로 관리
본인은 위에서 이야기했듯이, map으로 2개의 문자열에 대해서, 발생할 수 있는 올바른 문자열들의 갯수를 저장할 뿐 아니라, 발생할 수 있는 모든 문자열들을 중복되지 않게 모두 저장해 주었다.
이 때, vector를 사용해서 관리해 주었는데,
str1 = { "aa" , "bc" }
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 | #include <string> #include <vector> #include <map> #define MULTIPLE 65536 using namespace std; int Min(int A, int B) { return A < B ? A : B; } int Max(int A, int B) { return A > B ? A : B; } int Check_State(char C) { if ('A' <= C && C <= 'Z') return 2; if ('a' <= C && C <= 'z') return 1; return 0; } char Invert(char C) { C = C - 'A'; C = C + 'a'; return C; } int solution(string str1, string str2) { vector<string> Total_Str; map<string, int> A, B; /* str1에 대해서 "올바른 문자열" 추출하기. */ for (int i = 0; i < str1.length() - 1; i++) { char First = str1[i]; char Second = str1[i + 1]; int First_State = Check_State(First); int Second_State = Check_State(Second); if (First_State == 0 || Second_State == 0) continue; if (First_State == 2) First = Invert(First); if (Second_State == 2) Second = Invert(Second); string Temp = ""; Temp = Temp + First; Temp = Temp + Second; /* 전체 문자열을 관리할 때는, 중복되지 않게 삽입해야한다. */ /* 중복을 확인하기 위해서는 map에 이미 값이 있는지 확인하면 된다. */ if (A[Temp] == 0) Total_Str.push_back(Temp); A[Temp]++; } /* str2에 대해서 "올바른 문자열" 추출하기. */ for (int i = 0; i < str2.length() - 1; i++) { char First = str2[i]; char Second = str2[i + 1]; int First_State = Check_State(First); int Second_State = Check_State(Second); if (First_State == 0 || Second_State == 0) continue; if (First_State == 2) First = Invert(First); if (Second_State == 2) Second = Invert(Second); string Temp = ""; Temp = Temp + First; Temp = Temp + Second; /* str2에서 발생한 문자열도, 전체 문자열을 관리하는 vector에 값을 삽입해야함. */ /* 물론, 중복이 되지 않게 하기 위해서, map을 이용해서 판단. */ if (A[Temp] == 0 && B[Temp] == 0) Total_Str.push_back(Temp); B[Temp]++; } if (Total_Str.size() == 0) return MULTIPLE; int Intersection, Union; Intersection = Union = 0; for(int i = 0; i < Total_Str.size(); i++) { /* 교집합은, 두 집합 중 더 적은 갯수. */ /* 합집합은, 두 집합 중 더 큰 갯수. */ string Str = Total_Str[i]; Intersection = Intersection + Min(A[Str], B[Str]); Union = Union + Max(A[Str], B[Str]); } double answer = (double)Intersection / Union; answer = answer * MULTIPLE; return (int)answer; } | cs |
'[ Programmers Code ] > # PG - Level2' 카테고리의 다른 글
[ 프로그래머스 [1차] 캐시 (Lv2) ] (C++) (0) | 2020.09.09 |
---|---|
[ 프로그래머스 [1차] 프렌즈4블록 (Lv2) ] (C++) (0) | 2020.09.08 |
[ 프로그래머스 문자열 압축 (Lv2) ] (C++) (1) | 2020.09.08 |
[ 프로그래머스 단체사진 찍기 (Lv2) ] (C++) (0) | 2020.05.15 |
[ 프로그래머스 JadenCase문자열 만들기 (Lv2) ] (C++) (0) | 2020.05.15 |