대략 3일...
function solution(str1, str2) {
// 문자만 쓰는 정규식 패턴
let pattern = /[a-zA-Z]/;
// str1과 str2의 문자열을 2개씩 끊는다. 그것을 각각 배열 변수 str1Subset, str2Subset 이라 한다.
const strToSubsetTwoLetter = (str) => {
str = str.toLowerCase();
let result = [];
for (let i = 0; i < str.length - 1; i++) {
// 2개씩 끊는중 영문자로 된 글자 쌍만 result에 푸쉬한다.
if (pattern.test(str[i]) && pattern.test(str[i + 1])) {
result.push(str[i] + str[i + 1]);
}
}
return result;
};
const str1Subset = strToSubsetTwoLetter(str1); // [ 'ba', 'aa', 'aa', 'aa' ]
const str2Subset = strToSubsetTwoLetter(str2); // [ 'aa', 'aa' ]
console.log("27번쨰", str1Subset, str2Subset);
// str1Subset과 str2Subset의 교집합의 개수 intersection, 합집합의 개수 union을 구한다.
let intersectionCopy = [...str2Subset];
let duplicationLetter = "";
const intersection = str1Subset.filter((el) => {
if (intersectionCopy.includes(el)) {
duplicationLetter = el;
let idx = intersectionCopy.indexOf(el);
intersectionCopy.splice(idx, 1);
return true;
} else {
return false;
}
})
let union = [...str1Subset];
let unionCopy = [...str1Subset];
str2Subset.forEach((el) => {
if (unionCopy.includes(el)) {
duplicationLetter = el;
let idx = unionCopy.indexOf(el);
unionCopy.splice(idx, 1);
} else {
union.push(el);
}
});
// console.log("43번쨰", intersection, union);
// intersection / union * 65536 하고 소수점 아래를 버린 값을 리턴한다.
if (intersection.length === 0 && union.length === 0) {
return 65536
}
return Math.floor((intersection.length / union.length) * 65536);
}
console.log(solution("BAAAA", "AAA"));
정규식 표현은 간단하지만 아주 유용하다. 허나 매번 볼때마다 까먹기 때문에 체화가 필요하다.
아마 union intersection을 만들때 그냥 단순히 하게 되면 중복 요소에 대해 문제가 생긴다.
예를 들어
str1 = ["BA", "AA", "AA", ""AA"]
str2 = ["AA", ""AA"]
answer: 32768
일때 그냥 교집합을 하게 되면 str1이 그대로 나오게 된다.
따라서 str2를 copy하여 겹칠떄마다 str2의 요소들을 없앰으로써 처리를 하였다.
function solution(str1, str2) {
// 문자만 쓰는 정규식 패턴
let pattern = /[a-z]{2}/;
// str1과 str2의 문자열을 2개씩 끊는다. 그것을 각각 배열 변수 str1Subset, str2Subset 이라 한다.
const strToSubsetTwoLetter = (str) => {
str = str.toLowerCase();
let result = [];
for (let i = 0; i < str.length - 1; i++) {
// 2개씩 끊는중 영문자로 된 글자 쌍만 result에 푸쉬한다.
const tmp = str.substr(i, 2)
if (pattern.test(tmp)) {
result.push(tmp);
}
}
return result;
};
const str1Subset = strToSubsetTwoLetter(str1); // [ 'ba', 'aa', 'aa', 'aa' ]
const str2Subset = strToSubsetTwoLetter(str2); // [ 'aa', 'aa' ]
// console.log("20번쨰", str1Subset, str2Subset);
// str1Subset과 str2Subset의 교집합의 개수 intersection, 합집합의 개수 union을 구한다. 아이디어 신기
const arr1 = strToSubsetTwoLetter(str1);
const arr2 = strToSubsetTwoLetter(str2);
const set = new Set([...arr1, ...arr2]);
console.log("26번째", arr1, arr2, set)
let union = 0;
let intersection = 0;
set.forEach(item => {
const has1 = arr1.filter(x => x === item).length;
const has2 = arr2.filter(x => x === item).length;
union += Math.max(has1, has2);
intersection += Math.min(has1, has2);
})
// intersection / union * 65536 하고 소수점 아래를 버린 값을 리턴한다.
return union === 0 ? 65536 : Math.floor(intersection / union * 65536);
}
console.log(solution("handshake", "shake hands"));