https://school.programmers.co.kr/learn/courses/30/lessons/17677
function solution(str1, str2) {
let answer = 0;
// 문자열을 정제해서 다중 집합 만드는 함수
function makeMultiset(str) {
const resultArr = [];
const filteredStr = str.match(/[A-Za-z]/g).join('').toLowerCase();
for (let i = 0; filteredStr.length - 1 > i; i++) {
resultArr.push(filteredStr.substring(i, i + 2))
}
return resultArr;
}
const multi1 = makeMultiset(str1);
const multi2 = makeMultiset(str2);
...
}
위의 수도코드를 2번까지 코드로 구현했다.
그러나 구현하고 나서 문제를 발견했는데, 입출력 예시 2~4번 처럼 특수문자나 띄어쓰기가 포함된 문자열의 경우, 무조건 그 문자열을 걸러낸 뒤 다중집합을 구하면 안된다는 것이였다.
4번째 예시를 예로 들면, 내가 한 방식대로 먼저 특수문자를 모두 제거한 뒤, 다중집합을 구하면
[em, mc]가 나오지만, 문제에서 요구하는 것은 먼저 문자열을 자르고 그 자른 문자열에 특수문자가 포함되어있으면 버리는 것이였다.
사실 Javascript에서 지원하는 string의 다른 메서드를 활용해서 풀어볼 수 있다고 생각했지만, 정규표현식을 사용하는 것이 가장 깔끔하고 빠르다고 생각해서 정규표현식을 통한 풀이를 포기하기 싫었다. 그래서 다른 분들의 코드를 검색해보았다.
function solution (str1, str2) {
// 문제 조건에 맞는 다중집합을 만드는 함수.
function explode(text) {
const result = [];
for (let i = 0; i < text.length - 1; i++) {
const node = text.substr(i, 2);
if (node.match(/[A-Za-z]{2}/)) {
result.push(node.toLowerCase());
}
}
return result;
}
const arr1 = explode(str1);
const arr2 = explode(str2);
const set = new Set([...arr1, ...arr2]);
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);
})
return union === 0 ? 65536 : Math.floor(intersection / union * 65536);
}
여러 코드를 살펴봤지만 위 코드가 내가 생각한 가장 이상적인 코드였다.
explode 함수 내부에서 내가 구현하려 생각한 부분을 정규표현식으로 구현한 코드다. 정규표현식의 중괄호를 이용해서 두 글자씩 끊어서 if조건에 걸리면 배열에 넣고 그렇지않으면 넣지 않는 방식으로 문제에서 요구하는 조건을 구현하고 있다.
그리고 인상깊었던게 아래 union하고 intersection을 구하는 부분이였는데, 처음에 다중집합의 합집합에 대한 개념이 없어서, 중복된 숫자를 모두 제거해야하나 했지만, 그게아니라 다중집합은 중복된 요소를 허용하기 때문에, 내가 이전에 set을 통해 중복을 모두 제거하는 방식으로 구한 합집합은 허용되지 않았다.
그래서 위 코드에서는 먼저 set으로 arr1과 arr2를 합치고 중복을 제거한 다음 그것을 기준으로 arr1과 arr2의 각 요소에 filter와 length를 통해 갯수를 구하는 방식을 사용했다.
이 문제에서 부족했던 점은 다음과 같다.
1. 문제를 제대로 파악하지 못해서 문제에서 요구한 대로 문자열 정제를 제대로 하지 못한 점
2. 만약 문제를 제대로 파악했다고 해도, 정규표현식을 사용해서 문자열 정제를 하지 못했을 것 같다는 점 > 정규표현식의 중괄호 활용법을 이제서야 알았다...
3. 다중 집합이라는 개념을 알지 못해서 문제의 요구조건을 제대로 파악하지 못한 점
사실 이제 2번까지는 확실하게 알았다고 말할 수 있는데, 3번은 좀 아리까리하다. 정확히는 다중 집합의 개념은 알았지만, 다른 사람의 풀이에 적은 코드에서 set과 filter을 활용해서 union과 intersection에 최댓값, 최솟값을 계속 더하는 방식은 내가 나중에 혼자 풀 때, 다시 구현할 수 있을 까 하는 의문이 든다.