Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 배열에서 회문(팰린드롬) 요소만 골라내는 방법

이번 글에서는 문자열과 숫자가 섞여 있는 배열을 입력받아, 그중 회문(palindrome)에 해당하는 요소들만 모아 새로운 배열로 반환하는 JavaScript 함수를 만들어 보겠습니다.

문제 정의

예를 들어 다음과 같은 배열이 입력으로 주어졌다고 가정해 봅시다.

const arr = ['carecar', 1344, 12321, 'did', 'cannot'];

여기서 회문인 요소는 앞에서 읽으나 뒤에서 읽으나 같은 값들입니다. 따라서 기대되는 출력 결과는 다음과 같습니다.

const output = [12321, 'did'];

'carecar'는 뒤집으면 'racerac'가 되어 원래 값과 다르고, 1344 역시 뒤집으면 4431이 되므로 회문이 아닙니다. 반면 12321과 'did'는 거꾸로 읽어도 동일하므로 결과 배열에 포함됩니다.

해결 접근 방식

구현은 두 단계로 나눌 수 있습니다.

1단계: 회문 판별 헬퍼 함수 작성

숫자 또는 문자열 하나를 받아 해당 값이 회문인지 검사하는 함수를 먼저 만듭니다. 숫자의 경우 String()으로 문자열로 변환한 뒤, 양쪽 끝에서부터 포인터를 이동시키며 문자를 비교하는 두 포인터(two-pointer) 기법을 사용하면 효율적으로 판별할 수 있습니다.

2단계: filter()로 배열 순회

배열 전체를 순회하면서 각 요소에 헬퍼 함수를 적용하고, 회문인 요소만 남긴 새 배열을 반환합니다. JavaScript 내장 메서드인 Array.prototype.filter()를 활용하면 간결하게 처리할 수 있습니다.

구현 예제

위 접근 방식을 코드로 구현하면 다음과 같습니다.

const arr = ['carecar', 1344, 12321, 'did', 'cannot'];

// 회문 여부를 판별하는 헬퍼 함수
const isPalindrome = el => {
    const str = String(el); // 숫자도 문자열로 변환하여 처리
    let i = 0;
    let j = str.length - 1;
    while(i < j) {
        if(str[i] === str[j]) {
            i++;
            j--;
        } else {
            return false;
        }
    }
    return true;
};

// 회문 요소만 필터링하는 함수
const findPalindrome = arr => {
    return arr.filter(el => isPalindrome(el));
};

console.log(findPalindrome(arr));

실행 결과

콘솔에 출력되는 결과는 다음과 같습니다.

[ 12321, 'did' ]

코드 설명

  • String(el): 배열에는 숫자와 문자열이 섞여 있으므로, 모든 요소를 문자열로 통일해 비교할 수 있도록 변환합니다.
  • 두 포인터 비교: 시작 인덱스 i와 끝 인덱스 j를 양 끝에 두고 서로를 향해 이동시키며 문자를 비교합니다. 한 번이라도 불일치하면 즉시 false를 반환하므로 불필요한 연산을 줄일 수 있습니다.
  • filter(): 콜백 함수가 true를 반환하는 요소만 모아 새로운 배열을 생성하며, 원본 배열은 변경되지 않습니다.

이 알고리즘의 시간 복잡도는 O(n × m)입니다. 여기서 n은 배열의 요소 개수, m은 각 요소의 평균 길이입니다. 대부분의 실무 상황에서 충분히 효율적이며, 코드 역시 직관적이라 유지보수하기 좋습니다.