문제
풀이
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<string> v(string str){
char before= tolower(str[0]);
vector<string> vec;
for(int i=1; i<str.size(); i++){
if((before < 'a' || before > 'z')
|| (tolower(str[i]) < 'a' || tolower(str[i]) > 'z')) {
before = tolower(str[i]);
continue;
}
string s;
s.append(1, before).append(1, tolower(str[i]));
vec.push_back(s);
before = tolower(str[i]);
}
return vec;
}
int solution(string str1, string str2) {
float answer = 0;
int inter = 0, uni = 0; // 교, 합집합
vector<string> vec1,vec2 ;
vec1 = v(str1);
vec2 = v(str2);
uni += vec1.size() + vec2.size();
if(uni == 0) return 65536;
for(int i=0; i<vec1.size(); i++){
if(find(vec2.begin(), vec2.end(), vec1[i]) != vec2.end()){
inter++;
vec2.erase(find(vec2.begin(), vec2.end(), vec1[i]));
vec1.erase(vec1.begin() + i--);
}
}
cout << endl;
uni -= inter;
answer = (float)inter/uni;
return answer*65536/1;
}
두 글자씩 끊어서 다중집합을 만드는 함수를 만들었다.
find, erase함수를 사용하여 합집합, 교집합의 개수를 구하였다.
append
문자열 끝에 문자들을 붙이는 함수이다.
함수 원형
append(const string&str, size_type str_idx, size_type str_num)
- str : 추가할 문자열
- str_idx : 추가할 문자열의 시작 지점
- str_num : 시작 지점으로부터 몇 개의 글자를 추가할 것인지
append(size_type num, char c)
- c 문자열을 num개만큼 반복해서 붙인다.
다른 사람 풀이 1
#include <bits/stdc++.h>
using namespace std;
short a, b, C[676], D[676];
int solution(string A, string B) {
for(int i=1; i<A.size(); i++)
if(isalpha(A[i-1]) && isalpha(A[i]))
C[(A[i-1]&31)*26+(A[i]&31)]++;
for(int i=1; i<B.size(); i++)
if(isalpha(B[i-1]) && isalpha(B[i]))
D[(B[i-1]&31)*26+(B[i]&31)]++;
for(int i=0; i<676; i++) a+=min(C[i], D[i]), b+=max(C[i], D[i]);
return b ? a*65536/b : 65536;
}
다른 사람 풀이 2
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
using namespace std;
int solution(string str1, string str2) {
vector<int> multiset1 = vector<int>(676, 0);
vector<int> multiset2 = vector<int>(676, 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++) {
char first = str1[i];
char second = str1[i+1];
if (first >= 97 && first <= 122 && second >= 97 && second <= 122 ) {
multiset1[(first-97)*26 + (second-97)]++;
}
}
for (int i = 0; i < str2.length() - 1; i++) {
char first = str2[i];
char second = str2[i+1];
if (first >= 97 && first <= 122 && second >= 97 && second <= 122 ) {
multiset2[(first-97)*26 + (second-97)]++;
}
}
int numberOfIntersection = 0;
int numberOfUnion = 0;
for (int i = 0; i < 676; i++) {
numberOfUnion += max(multiset1[i], multiset2[i]);
numberOfIntersection += min(multiset1[i], multiset2[i]);
}
if(numberOfUnion == 0)
return 65536;
else
return (int)(((double) numberOfIntersection / (double) numberOfUnion) * (double) 65536);
}
두 풀이 모두 알파벳 두 개를 인덱스로 만드는 방법을 사용했다.
*26을 해준 이유는 알파벳 개수가(소문자만) 26개이고, ab와 ba의 경우 인덱스를 다르게 주기 위함이다.
-97을 해 준 이유는 아스키코드표에 97이 'a'에 해당하기 때문이다
transform
<algorithm>에 정의되어있다.
특정 함수를 써서 값을 변경해야 할 때 유용한 함수이다.
함수 원형
transform(InputIt first 1, InputIt last 1, OutputIt d_first, UnaryOperation unary_op);
- first 1, last 1 : transform 함수를 적용할 원소들을 가리키는 범위
- d_first : 결과를 저장할 범위. (first 1과 동일할 경우 기존 데이터를 덮어쓰게 된다.)
- unary_op : 원소들을 변환할 함수
transform(str.begin(), str.end(), str.begin(), ::tolower);
- 위의 코드로 str의 모든 문자를 소문자로 만들 수 있다.
isalpha
알파벳을 확인하는 함수.
알파벳일 경우 0이 아닌 수를 반환하고, 알파벳이 아닐 경우 0을 반환한다.
isalpha (int c);
isalpha 함수의 매개변수로
- 아스키코드표에 'A-Z'에 해당하는 65번~90번의 값이 들어오면 1을 반환한다.
- 아스키코드표에 'a-z'에 해당하는 97번~122번의 값이 들어오면 2를 반환한다.
- 알파벳이 아닌 것은 0을 반환한다.
https://jhnyang.tistory.com/115
https://artist-developer.tistory.com/28
https://blockdmask.tistory.com/448
'Algorithm > 카카오기출' 카테고리의 다른 글
[프로그래머스] 거리두기 확인하기 (0) | 2022.06.06 |
---|---|
[프로그래머스] 메뉴 리뉴얼 / substr, 순열과 조합 (0) | 2022.05.16 |
[프로그래머스] 괄호 변환 / substr (0) | 2022.04.11 |
[프로그래머스] 단체사진찍기 / DFS, assign, next_permutation (0) | 2022.03.22 |
[프로그래머스] 카카오프렌즈 컬러링북 / DFS과 BFS, memset (0) | 2022.03.11 |