아나그램(Anagram)이란?
아나그램은 한 문자열의 글자 순서를 재배열했을 때 다른 문자열과 완전히 동일해지는 문자열 쌍을 의미합니다.
예를 들어 'hello'와 'lolhe'는 아나그램입니다. 'lolhe'의 글자들을 적절히 재배열하면 'hello'를 만들 수 있고, 그 반대도 가능하기 때문입니다.
이번 글에서는 두 개의 문자열(str1, str2)을 인자로 받아, 두 문자열이 서로 아나그램이면 true, 그렇지 않으면 false를 반환하는 JavaScript 함수를 작성해 보겠습니다.
접근 방식
가장 효율적인 방법은 각 문자열마다 문자별 등장 횟수를 집계하는 맵(객체)을 만든 뒤, 두 맵을 비교하여 완전히 일치하는지 확인하는 것입니다.
처리 과정을 단계별로 정리하면 다음과 같습니다.
- 정규식(
/\W/g)으로 공백과 특수문자를 제거하고, 모든 글자를 소문자로 통일합니다. - 각 문자열의 문자별 개수를 객체에 저장합니다.
- 두 객체의 키(고유 문자) 개수가 다르면 즉시
false를 반환합니다. - 키 개수가 같다면 각 문자의 등장 횟수가 모두 일치하는지 하나씩 비교합니다.
예제 코드
const str1 = 'hello';
const str2 = 'lolhe';
const charCount = string => {
const table = {};
for (let char of string.replace(/\W/g, "").toLowerCase()) table[char] = table[char] + 1 || 1;
return table;
};
const anagrams = (stringA, stringB) => {
const charCountA = charCount(stringA);
const charCountB = charCount(stringB);
if (Object.keys(charCountA).length !== Object.keys(charCountB).length)
return false;
for (let char in charCountA)
if (charCountA[char] !== charCountB[char])
return false;
return true;
};
console.log(anagrams(str1, str2));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
true
'hello'와 'lolhe'는 서로 아나그램 관계이므로 함수가 true를 반환한 것을 확인할 수 있습니다. 이 방식은 각 문자열을 한 번씩만 순회하므로 시간 복잡도가 O(n)으로, 문자열 정렬 후 비교하는 방법(O(n log n))보다 더 효율적입니다.