https://school.programmers.co.kr/learn/courses/30/lessons/17677
문자 A, B의 자카드 유사도 J(A,B)를 구하는 문제다
구하는 방법은 두 집합의 교집합 크기를 합집합의 크기로 나누면 된다.
입력
- str1, str2
- 2 이상 1000이하의 길이를 가진 문자열
출력
자카드 유사도에 65536을 곱한후 소숫점을 버린후 출력한다
function getStr(str) {
const arr = [];
const reg = /[A-Z]/;
for (let i = 0; i < str.length - 1; i++) {
const left = reg.test(str[i]);
const right = reg.test(str[i + 1]);
if (left && right) {
arr.push([str[i], str[i + 1]].join(''));
}
}
return arr;
}
const getIntersection = (arr1, arr2) => {
const result = [];
for (let i = 0; i < arr1.length; i++) {
if (arr2.includes(arr1[i])) {
const idx = arr2.indexOf(arr1[i]);
result.push(arr2[idx]);
arr2.splice(idx, 1);
}
}
return result.length;
};
function solution(str1, str2) {
const arr1 = getStr(str1.toUpperCase());
const arr2 = getStr(str2.toUpperCase());
let intersection = getIntersection([...arr1], [...arr2]);
let union = arr1.length + arr2.length - intersection;
const result = Math.floor((intersection / union) * 65536);
if(union === 0) return 65536;
if(intersection === 0) return 0;
return result;
}
합집합을 구하는 방법은 두 집합의 크기 - 교집합의 크기
이다.
그래서 우선 교집합을 구해야 하는데 그 전에 집합을 만들어준다.
function getStr(str) {
const arr = [];
const reg = /[A-Z]/;
for (let i = 0; i < str.length - 1; i++) {
const left = reg.test(str[i]);
const right = reg.test(str[i + 1]);
if (left && right) {
arr.push([str[i], str[i + 1]].join(''));
}
}
return arr;
}
집합을 구하는 함수인데 0부터 시작해 문자열길이 -1까지 탐색을 한다.
그러고서 만약 특수문자가 있다면 집합에 포함하지 않고 없다면 집합에 포함시켜준다.
const getIntersection = (arr1, arr2) => {
const result = [];
for (let i = 0; i < arr1.length; i++) {
if (arr2.includes(arr1[i])) {
const idx = arr2.indexOf(arr1[i]);
result.push(arr2[idx]);
arr2.splice(idx, 1);
}
}
return result.length;
};
위의 코드는 교집합을 구하는 함수다.
집합 arr1, arr2를 입력받은후에 arr1을 for문으로 돌아본다.
그러고서 arr1[i]가 arr2[i]에 있다면 arr2에서 해당 원소를 제거한다.
만약 제거하지 않으면 나와야 하는 값보다 더 크게 나올수도 있으므로 꼭 제거해야 한다.
let intersection = getIntersection([...arr1], [...arr2]);
let union = arr1.length + arr2.length - intersection;
const result = Math.floor((intersection / union) * 65536);
if(union === 0) return 65536;
if(intersection === 0) return 0;
return return result;
문제에 나온대로 교집합 / 합집합 * 65536 후에 소수점을 버린다.
그 후에 비교할 집합이 아에 없으면(양쪽다 공집합이면) 65536을 리턴하고
교집합으로 나온값이 없다면 0을 리턴한다.
둘다 아니라면 result로 나온 값을 리턴해주면 된다