https://school.programmers.co.kr/learn/courses/30/lessons/17677
문자열의 유사도를 비교해서 출력하는 문제
function solution(str1, str2) {
const TIMES_NUMBER = 65536
const str1Arr = [];
const str2Arr = [];
const str1Obj = {};
const str2Obj = {};
let result;
const regex = /^[a-zA-Z]+$/;
const splitStr = (str,arr) => {
const deque = [];
[...str.toUpperCase()].forEach(el => {
if(!regex.test(el)) return deque.pop();
if(!deque.length) return deque.push(el);
deque.push(el);
arr.push(deque.join(''))
deque.shift();
})
}
const makeObj = (arr,obj) => {
arr.forEach(el => {
if(!obj[el]) obj[el] = 0
obj[el] += 1;
})
}
const countIntersection = (obj1, obj2) => {
const intersection = {};
for(str in obj1){
if(obj2[str]) intersection[str] = Math.min(obj1[str],obj2[str])
}
return Object.entries(intersection).reduce((acc,cur) => acc += cur[1],0)
}
const countUnion = (obj1, obj2) => {
const union = {};
for(str in obj1){
union[str] = obj1[str];
}
for(str in obj2){
union[str] = obj2[str]
if(obj1[str]) union[str] = Math.max(obj1[str],obj2[str]);
}
return Object.entries(union).reduce((acc,cur) => acc += cur[1],0)
}
splitStr(str1, str1Arr);
splitStr(str2, str2Arr);
if(!str1Arr.length && !str2Arr.length) return TIMES_NUMBER
makeObj(str1Arr, str1Obj);
makeObj(str2Arr, str2Obj);
result = Math.floor(countIntersection(str1Obj, str2Obj) / countUnion(str1Obj, str2Obj) * TIMES_NUMBER)
return result
}
오히려 고민은 적었던 것 같다
해야하는 게 명확해서 그것을 하나씩 구현하면 됐던 문제
문제는 시간이 너무 오래걸렸다는 것인데
이거 푸는데 한 시간이나 걸려버렸다
const regex = /^[a-zA-Z]+$/;
const splitStr = (str,arr) => {
const deque = [];
[...str.toUpperCase()].forEach(el => {
if(!regex.test(el)) return deque.pop();
if(!deque.length) return deque.push(el);
deque.push(el);
arr.push(deque.join(''))
deque.shift();
})
}
입력받은 str을 요소를 정규식으로 문자인지 확인 후에 deque에 넣고
문자를 두 글자씩 배열에 넣어주는 함수
const makeObj = (arr,obj) => {
arr.forEach(el => {
if(!obj[el]) obj[el] = 0
obj[el] += 1;
})
}
배열의 요소를 객체에 { str : 배열 내의 str 개수 }의 형태로 저장
const countIntersection = (obj1, obj2) => {
const intersection = {};
for(str in obj1){
if(obj2[str]) intersection[str] = Math.min(obj1[str],obj2[str])
}
return Object.entries(intersection).reduce((acc,cur) => acc += cur[1],0)
}
입력받은 객체들의 교집합 수를 리턴
const countUnion = (obj1, obj2) => {
const union = {};
for(str in obj1){
union[str] = obj1[str];
}
for(str in obj2){
union[str] = obj2[str]
if(obj1[str]) union[str] = Math.max(obj1[str],obj2[str]);
}
return Object.entries(union).reduce((acc,cur) => acc += cur[1],0)
}
입력받은 객체들의 합집합 수를 리턴
splitStr(str1, str1Arr);
splitStr(str2, str2Arr);
if(!str1Arr.length && !str2Arr.length) return TIMES_NUMBER
makeObj(str1Arr, str1Obj);
makeObj(str2Arr, str2Obj);
result = Math.floor(countIntersection(str1Obj, str2Obj) / countUnion(str1Obj, str2Obj) * TIMES_NUMBER)
return result
위의 함수들을 사용해서 정답을 리턴해줬다