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

JavaScript로 문자열에서 알파벳만 반전시키는 방법

문제 이해하기

알파벳과 일부 특수 문자가 섞여 있는 문자열 str을 입력받는 JavaScript 함수를 작성해야 합니다.

이 함수는 입력 문자열을 기반으로 새로운 문자열을 반환해야 하며, 이때 알파벳이 아닌 문자는 원래 자리에 그대로 유지되고, 알파벳 문자들만 서로 위치를 뒤바꿔야 합니다.

예를 들어 함수에 다음과 같은 입력이 주어졌다고 가정해 보겠습니다.

입력

const str = 'k_lmn_opq';

출력

const output = 'q_pon_mlk';

위 결과를 보면 언더스코어(_)의 위치는 변하지 않았지만, 알파벳들만 정확히 역순으로 배치된 것을 확인할 수 있습니다.

해결 접근 방식: 투 포인터(Two Pointer)

이 문제는 투 포인터 기법을 사용하면 시간 복잡도 O(n)으로 효율적으로 해결할 수 있습니다. 동작 과정은 다음과 같습니다.

  • 문자열을 배열로 분할(split)한 후, 왼쪽 포인터(left)와 오른쪽 포인터(right)를 양 끝에 배치합니다.
  • 왼쪽 포인터는 알파벳이 아닌 문자를 만나면 한 칸씩 앞으로 이동하여 건너뜁니다.
  • 오른쪽 포인터는 알파벳이 아닌 문자를 만나면 한 칸씩 뒤로 이동하여 건너뜁니다.
  • 양쪽 포인터가 모두 알파벳을 가리키면 두 문자를 교환(swap)하고, 각 포인터를 안쪽으로 한 칸씩 이동시킵니다.
  • 포인터가 서로 교차하면 반복을 종료하고 배열을 다시 문자열로 합칩니다(join).

예제 코드

const str = 'k_lmn_opq';

const reverseAlphabets = (str) => {
    const arr = str.split('')
    let left = 0
    let right = arr.length - 1

    // 배열 내 두 요소의 위치를 교환하는 헬퍼 함수
    const swap = (a, b) => {
        const temp = arr[a]
        arr[a] = arr[b]
        arr[b] = temp
    }

    // 해당 문자가 알파벳인지 판별하는 헬퍼 함수
    const isLetter = (x = '') => /[a-zA-Z]/.test(x)

    while (left <= right) {
        // 왼쪽부터 알파벳이 아닌 문자 건너뛰기
        while (!isLetter(arr[left])) {
            left += 1
            if (left > right) {
                break
            }
        }
        // 오른쪽부터 알파벳이 아닌 문자 건너뛰기
        while (!isLetter(arr[right])) {
            right -= 1
            if (left > right) {
                break
            }
        }
        if (left > right) {
            break
        }
        // 양쪽 알파벳 위치 교환 후 포인터 이동
        swap(left, right)
        left += 1
        right -= 1
    }
    return arr.join('')
};

console.log(reverseAlphabets(str));

실행 결과

q_pon_mlk

코드 핵심 정리

  • isLetter 함수는 정규 표현식 /[a-zA-Z]/을 사용해 해당 문자가 영문 알파벳인지 빠르게 판별합니다.
  • 내부 while 루프에서 포인터가 범위를 벗어나지 않도록 left > right 조건 검사를 반드시 포함해야 무한 루프나 인덱스 오류를 방지할 수 있습니다.
  • 문자열 대신 배열을 사용해 교환 연산을 수행하므로, 전체 시간 복잡도는 O(n), 공간 복잡도 역시 O(n)입니다.