728x90
반응형
문제설명
문제분석
이 문제는 (1) 두 문자열을 입력받아 각 문자열에 대해 2글자씩 끊어서 집합을 만드는 문제와 (2) 두 집합의 교집합과 합집합의 길이를 구하고 자카드 유사도를 계산하는 문제로 구분할 수 있습니다. 각 문제별로 살펴보면 다음과 같습니다.
- 두 문자열을 입력받아 각 문자열에 대해 2글자씩 끊어서 집합을 만드는 문제
- 두 문자열이지만, 결국 하나의 함수를 작성해서 두 문자열에 대해 함수를 호출한다.
- 반복문을 돌면서 i번째 요소 + (i+1)번째 요소가 각각 문자인 경우, toLowerCase를 적용해 결과에 저장한다
- 반복문이 끝나면 결과를 리턴한다.
- 두 집합의 교집합과 합집합의 길이를 구하고 자카드 유사도를 계산하는 문제
- 두 집합(A, B)의 교집합을 구하기 위해서는 집합 A를 순회하며 집합 B에 존재하는 요소를 확인하면 된다.
문제를 단순화 했으니 이해하기 쉽게 코드를 짜보겠습니다.
반응형
이해하기 쉽게 코드작성하기
function solution(str1, str2) {
const CONSTANT = 65536;
const [setStr1, setStr2] = [genSet(str1), genSet(str2)];
if(setStr1.length === 0 && setStr2.length === 0) return CONSTANT;
const interLen = getIntersectionLength(setStr1, setStr2);
const unionLength = setStr1.length + setStr2.length - interLen;
return Math.floor((interLen / unionLength) * CONSTANT);
}
// 두 배열의 교집합의 길이를 리턴
function getIntersectionLength(arr1, arr2) {
const result = [];
let tmpArr2 = [...arr2];
return arr1.map(x => {
const idx = tmpArr2.indexOf(x);
if(idx > -1) {
tmpArr2 = tmpArr2.slice(0, idx).concat(tmpArr2.slice(idx + 1));
return true;
}
return false;
}).filter(x => x).length;
}
// 문자열을 2글자씩 끊어 배열로 만들어 리턴
function genSet(str) {
str = str.toLowerCase();
const result = [];
for(let i = 0; i < str.length - 1; i++) {
if(isAlphabet(str[i]) && isAlphabet(str[i + 1])) {
result.push(str[i] + str[i + 1]);
}
}
return result;
}
// 문자가 알파벳인지 검사
function isAlphabet(ch) {
return 97 <= ch.charCodeAt() && ch.charCodeAt() <= 122;
}
합집합의 길이는 집합 A의 길이에 집합 B의 길이를 더하고, 마지막으로 두 집합의 교집합의 길이를 빼면 됩니다. 이 문제에서는 교집합의 길이만 구할 수 있으면 되기때문에 위 코드로도 충분히 깔끔하다고 생각하지만, Set을 사용해 교집합의 길이와 합집합의 길이를 구하는 부분을 조금 더 직관적으로 변경할 수 있습니다.
function solution(str1, str2) {
const CONSTANT = 65536;
const [setStr1, setStr2] = [genSet(str1), genSet(str2)];
if(setStr1.length === 0 && setStr2.length === 0) return CONSTANT;
const set = new Set([...setStr1, ...setStr2]);
let interLen = 0, unionLen = 0;
set.forEach(x => {
const existsLen1 = setStr1.filter(y => x === y).length;
const existsLen2 = setStr2.filter(y => x === y).length;
interLen += Math.min(existsLen1, existsLen2);
unionLen += Math.max(existsLen1, existsLen2);
});
return Math.floor((interLen / unionLen) * CONSTANT);
}
function genSet(str) {
str = str.toLowerCase();
const result = [];
for(let i = 0; i < str.length - 1; i++) {
if(isAlphabet(str[i]) && isAlphabet(str[i + 1])) {
result.push(str[i] + str[i + 1]);
}
}
return result;
}
function isAlphabet(ch) {
return 97 <= ch.charCodeAt() && ch.charCodeAt() <= 122;
}
728x90
반응형
'Practice for coding test' 카테고리의 다른 글
프로그래머스 - Level 2. 2개 이하로 다른 비트 / JavaScript (js) (0) | 2023.03.04 |
---|---|
프로그래머스 - Level 2. k진수에서 소수 개수 구하기 / JavaScript (js) (0) | 2023.03.03 |
프로그래머스 - Level 2. 스킬트리 / JavaScript (js) (0) | 2023.03.01 |
프로그래머스 - Level 2. [1차] 캐시 / JavaScript (js) (0) | 2023.02.28 |
프로그래머스 - Level 2. 할인 행사 / JavaScript (js) (0) | 2023.02.27 |