1. 문제
제한사항
입출력 예
출력 형식
2. 오답
function solution(str1, str2) {
const arr1 = new Map(); // str1을 두 글자씩 끊어서 만든 다중집합의 원소
const arr2 = new Map(); // str2를 두 글자씩 끊어서 만든 다중집합의 원소
let cntUnion = 0; // 합집합 카운트
let cntIntersection = 0; // 교집합 카운트
// 비교를 위해 소문자로 통일
str1 = str1.toLowerCase();
str2 = str2.toLowerCase();
for (let i=0; i<str1.length-1; i++) {
// 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
// 조건에 충족하면 arr1(Map)에 value+1
if (str1[i].match(/[a-z]/) && str1[i+1].match(/[a-z]/)) {
const t = str1[i] + str1[i+1];
if (arr1.has(t)) arr1.set(t, arr1.get(t)+1);
else arr1.set(t, 1);
}
}
for (let i=0; i<str2.length-1; i++) {
// 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
// 조건에 충족하면 arr2(Map)에 value+1
if (str2[i].match(/[a-z]/) && str2[i+1].match(/[a-z]/)) {
const t = str2[i] + str2[i+1];
if (arr2.has(t)) arr2.set(t, arr2.get(t)+1);
else arr2.set(t, 1);
}
}
// 합집합 카운트를 위한 Map 객체 (arr2를 깊은 복사)
const arrUnion = new Map(JSON.parse(JSON.stringify(Array.from(arr2))));
for (let [key, value] of arr1.entries()) {
// arr1과 arr2에 모두 포함된 값인 경우 value를 더 큰 값으로 세팅
if (arrUnion.get(key)) arrUnion.set(key, Math.max(value, arrUnion.get(key)));
// arr2에 없는 key 값이면 추가
else arrUnion.set(key, value);
// arr1과 arr2에 모두 포함된 값인 경우 둘의 최솟값을 더함
cntIntersection += Number(Math.min(value, arr2.get(key))) ? Math.min(value, arr2.get(key)) : 0;
}
// 합집합 수 카운트
Array.from(arrUnion.values()).forEach(a => cntUnion += a);
if (cntUnion < 1 || cntIntersection < 1) return 65536;
else return Math.floor(cntIntersection / cntUnion * 65536);
}
어디서 틀렸는지 모르겠다... 제한 사항 다시 읽어보면서 해결해야겠다...😂😂
3. 정답 풀이
function solution(str1, str2) {
const arr1 = new Map(); // str1을 두 글자씩 끊어서 만든 다중집합의 원소
const arr2 = new Map(); // str2를 두 글자씩 끊어서 만든 다중집합의 원소
let cntUnion = 0; // 합집합 카운트
let cntIntersection = 0; // 교집합 카운트
// 비교를 위해 소문자로 통일
str1 = str1.toLowerCase();
str2 = str2.toLowerCase();
for (let i=0; i<str1.length-1; i++) {
// 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
// 조건에 충족하면 arr1(Map)에 value+1
if (str1[i].match(/[a-z]/) && str1[i+1].match(/[a-z]/)) {
const t = str1[i] + str1[i+1];
if (arr1.has(t)) arr1.set(t, arr1.get(t)+1);
else arr1.set(t, 1);
}
}
for (let i=0; i<str2.length-1; i++) {
// 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
// 조건에 충족하면 arr2(Map)에 value+1
if (str2[i].match(/[a-z]/) && str2[i+1].match(/[a-z]/)) {
const t = str2[i] + str2[i+1];
if (arr2.has(t)) arr2.set(t, arr2.get(t)+1);
else arr2.set(t, 1);
}
}
// 합집합 카운트를 위한 Map 객체 (arr2를 깊은 복사)
const arrUnion = new Map(JSON.parse(JSON.stringify(Array.from(arr2))));
for (let [key, value] of arr1.entries()) {
// arr1과 arr2에 모두 포함된 값인 경우 value를 더 큰 값으로 세팅
if (arrUnion.get(key)) arrUnion.set(key, Math.max(value, arrUnion.get(key)));
// arr2에 없는 key 값이면 추가
else arrUnion.set(key, value);
// arr1과 arr2에 모두 포함된 값인 경우 둘의 최솟값을 더함
cntIntersection += Number(Math.min(value, arr2.get(key))) ? Math.min(value, arr2.get(key)) : 0;
}
// 합집합 수 카운트
Array.from(arrUnion.values()).forEach(a => cntUnion += a);
if (cntUnion < 1) return 65536;
else return Math.floor(cntIntersection / cntUnion * 65536);
}
집합 A와 집합 B가 모두 공집합일 경우에는 나눗셈이 정의되지 않으니 따로 J(A, B) = 1로 정의한다.
위 제한 사항 문구를 보고 아래처럼 조건식으로 교집합 or 합집합이 0인 경우 1을 리턴(65536을 출력에 곱해야 하기 때문에 1은 생략)해서 통과를 못했다.
if (cntUnion < 1 || cntIntersection < 1) return 65536;
합집합이 0인 경우는 나눗셈이 성립 안되기 때문에 1을 리턴하는 게 맞지만, 교집합이 없는 경우는 0을 리턴해야 한다.
조금만 생각하고 조건문 작성했으면 고생할 일도 없었을 텐데... 그래도 덕분에 코드 다시 정독해 보고 좋은 기회였다고 생각하자😅😅😅
'코딩 테스트 > 프로그래머스(LV2)' 카테고리의 다른 글
[프로그래머스] 게임 맵 최단 거리 (LV2 - JavaScript) (2) | 2024.11.19 |
---|---|
[프로그래머스] 타겟 넘버 (LV2 - JavaScript) (3) | 2024.11.19 |
[프로그래머스] 전화번호 목록 (LV2 - JavaScript) (3) | 2024.11.16 |
[프로그래머스] 프로세스 (LV2 - JavaScript) (5) | 2024.11.16 |
[프로그래머스] 튜플 (LV2 - JavaScript) (5) | 2024.11.15 |