유효한 팰린드롬 풀이: 알파벳만 남겨 회문을 판별하는 방법

··설명 약 10분·작성: 해비·블로그 소개

읽기 전에 알아두면 좋아요

아래 개념이 익숙하면 본문을 바로 읽으세요. 낯선 개념만 링크에서 복습하면 됩니다.

개념과 예제는 실행하지 않아도 읽을 수 있습니다. 내 컴퓨터·터미널에서 직접 실행하는 과정은 선택 실습입니다.

과정 위치와 선택 복습 안내

과정 위치: 문자열 응용 · 문제

과정 위치는 이 글이 속한 묶음입니다. 이 단계의 모든 개념을 먼저 읽을 필요는 없습니다. 위에 연결한 개념 중 낯선 내용만 복습하세요. 문제의 조건·상태·갱신 순서는 익숙한 언어로 설명하면 됩니다.

다른 풀이와 비용 비교 (선택)

JavaScript로 문법·실행 복습하기 (선택)

개념 글의 코드는 JavaScript 예시입니다. 문제 화면에서는 JavaScript·Python·Java·C++·C# 중 익숙한 언어의 함수를 작성하세요. 본문의 Node.js 입출력 예시는 로컬 실행을 위한 별도 안내입니다.

유효한 팰린드롬 문제는 어떤 문자와 대소문자 조건으로 회문인지 판단하나요?

영문 알파벳만 비교하고 대소문자를 구분하지 않을 때 회문인지 판별하는 문제입니다. 문자열·문자 범위·조건문의 기본을 준비하고, 아래 입력·반환 계약을 확인해 직접 풀어보세요.

적용 조건·범위: 비교 대상: 원본 TXT의 풀이처럼 영문 알파벳 a~z를 기준으로 처리합니다. 숫자도 제외합니다.

본문 근거: MDN replace 문서 · MDN reverse 문서

문제·입출력·제약

문자열에서 알파벳 이외의 문자를 무시하고, 대소문자를 구분하지 않았을 때 앞뒤로 읽은 순서가 같은지 판별합니다. 같으면 YES, 다르면 NO를 출력합니다.

  • 입력: 첫 줄의 문자열 하나입니다.
  • 길이: 100을 넘지 않습니다. 원문에는 별도의 최소 길이가 명시되어 있지 않습니다.
  • 비교 대상: 원본 TXT의 풀이처럼 영문 알파벳 a~z를 기준으로 처리합니다. 숫자도 제외합니다.
  • 출력: 판별 결과를 대문자로 한 줄에 출력합니다.

원본의 입력 설명에는 “공백이 없는 문자열”이라고 적혀 있지만, PDF와 TXT의 예제에는 공백이 포함되어 있습니다. 아래 풀이는 예제를 온전히 읽도록 첫 줄 전체를 입력받고, 공백을 포함한 알파벳 이외의 문자를 검사 전에 제거합니다. 공백으로 입력을 나누어 첫 단어만 사용하지 않습니다.

제공된 알고리즘 자료의 「섹션 3. 문자열 탐색.pdf」 2쪽과 「2. 유효한 팰린드롬.txt」를 2026년 10월 12일 직접 확인했습니다. 원본 TXT는 HTML 안에서 함수에 문자열을 전달하는 예제이며, 특정 온라인 채점 사이트는 제시되어 있지 않습니다. 문제 조건은 그대로 두고 실습창의 주 풀이는 양끝 비교로 설명합니다. 원본 TXT의 뒤집기 방식과 Node.js 표준 입력 코드는 아래에 대안 풀이로 보존했습니다.

원본 예제 입력

found7, time: study; Yduts; emit, 7Dnuof

원본 예제 출력

YES

목차

바로 코드를 보기 전에 원본 예제에서 숫자, 공백, 문장부호에 선을 그어 지워 보세요.

  1. 남은 문자의 대소문자가 다르면 어떤 기준으로 통일해야 할까요?
  2. 비교 대상인 알파벳의 순서가 앞에서 읽을 때와 뒤에서 읽을 때 같은지 어떻게 확인할까요?
  3. 숫자 7을 남겨도 되는지, 문제의 비교 대상을 다시 확인해 보세요.

회문 비교에 앞서 “비교할 문자열을 만드는 일”을 따로 떼어 생각하는 것이 이번 문제의 핵심입니다.

직접 풀어보기

먼저 선택한 언어의 입력·반환 계약에 맞춰 작성해 보세요. 힌트 받기와 정답과 비교하기는 코드를 실행하지 않는 AI 분석입니다. 해답·해설은 아래에서 필요할 때 펼칠 수 있습니다.

0 / 6,000바이트

첫 줄 전체에서 영문 알파벳만 비교하고 숫자·공백·기호를 제외해 회문 여부 YES 또는 NO를 반환합니다. 입력 예시 전체를 문자열 input으로 전달하고 출력 문자열을 반환합니다. solve(input)를 호출합니다. 표준 입력·출력 코드는 추가하지 않습니다. LF·CRLF·끝 줄바꿈 없음에 같은 결과를 반환합니다. Tab은 다음 항목으로 이동합니다. 입력 영역 오른쪽 아래를 끌어 높이를 조절할 수 있습니다.

비밀키·개인정보는 입력하지 마세요. 코드는 이 페이지에만 유지됩니다.

해답·해설 보기
JavaScript 해답
function solve(input) {
    const text = input.split(/\r?\n/, 1)[0];
    const letters = text.toLowerCase().replace(/[^a-z]/g, '');
    let left = 0;
    let right = letters.length - 1;
    while (left < right) {
        if (letters[left] !== letters[right]) return 'NO';
        left++;
        right--;
    }
    return 'YES';
}

첫 줄 전체에서 영문 알파벳만 비교하고 숫자·공백·기호를 제외해 회문 여부 YES 또는 NO를 반환합니다. 입력 예시 전체를 문자열 input으로 전달하고 출력 문자열을 반환합니다. solve(input)를 호출합니다. 표준 입력·출력 코드는 추가하지 않습니다. LF·CRLF·끝 줄바꿈 없음에 같은 결과를 반환합니다.

접근 과정

실습창의 JavaScript 정답은 solve(input)에 입력 예시 전체를 전달하고 YES 또는 NO를 반환합니다. 표준 입력을 읽거나 화면에 출력하는 코드는 넣지 않습니다. 첫 줄 전체를 소문자로 바꾸고 영문 알파벳만 남기는 전처리 뒤, 두 인덱스로 대칭 위치를 비교합니다.

  1. left는 첫 문자, right는 마지막 문자의 인덱스로 시작합니다.
  2. 두 문자가 다르면 남은 위치를 확인하지 않고 NO를 반환합니다.
  3. 같으면 left를 1 늘리고 right를 1 줄입니다. 두 위치가 만나거나 지나칠 때까지 모든 쌍이 같으면 YES입니다.

반복을 시작할 때 두 인덱스 바깥의 대칭 쌍은 이미 일치합니다. 같은 현재 쌍을 제외해도 이 성질은 유지되고, 서로 다른 쌍이 하나라도 있으면 회문일 수 없습니다. 가운데 한 문자는 자기 자신과 대응하므로 따로 비교하지 않습니다.

양끝 비교 추적

별도로 만든 작은 확인 입력
입력과 전처리 비교 결과
A,b!A → aba (0,2)의 a가 같습니다. (1,1)에서 종료합니다. YES
a,b:c;a → abca (0,3)은 같지만 (1,2)의 b와 c가 다릅니다. NO

실습창과 같은 JavaScript 함수

주 풀이의 시간·공간

원문 길이를 n, 남은 알파벳 수를 m이라 하면 첫 줄 읽기·소문자 변환·필터링에 O(n), 양끝 비교에 최대 O(m)이 걸려 전체 시간은 O(n)입니다. 첫 비교에서 종료해도 전처리 비용은 이미 들었습니다. 입력과 전처리 문자열 저장을 포함한 공간은 O(n)이고, 전처리 결과를 제외한 비교 루프의 추가 상태는 인덱스 두 개로 O(1)입니다. 반환하는 YES/NO 문자열은 O(1)입니다.

아래 원자료 대안은 같은 전처리 뒤 역순 문자열을 만들어 비교합니다. 두 방식 모두 전체 시간·공간은 O(n)이지만 주 풀이는 역순 문자열을 따로 만들지 않습니다. 입력 조건과 반환 결과는 같으며, 코드를 읽을 때는 지금 설명하는 방식이 어느 쪽인지 구분하세요.

대안 풀이: 원자료의 뒤집기 비교

다음 설명·전체 실행 코드·과거 실행 기록은 원본 TXT의 뒤집기 방식에 대한 것입니다. 실습창의 양끝 비교 함수를 교체하거나 함께 붙여 넣는 코드가 아닙니다.

1. 소문자로 통일한 뒤 알파벳만 남깁니다

toLowerCase()로 대소문자를 통일합니다. 그다음 /[^a-z]/g에 해당하는 문자를 빈 문자열로 바꿉니다. 대괄호 안의 ^는 “이 범위가 아닌 문자”를 뜻하고, a-z는 소문자 영문 알파벳 범위입니다. 끝의 g는 일치하는 문자를 하나만 바꾸지 않고 전체에서 찾아 바꾸게 합니다.

소문자 변환을 먼저 하므로 대문자도 소문자로 바뀌어 살아남습니다. 반대로 대문자가 섞인 상태에서 [^a-z]부터 적용하면 비교해야 할 대문자를 지울 수 있습니다. 또한 \W는 숫자와 밑줄을 남길 수 있어, 이 문제의 “알파벳만”이라는 조건을 그대로 표현하지 못합니다.

2. 뒤집은 문자열을 만들어 비교합니다

정리된 문자열을 letters에 저장합니다. split('')으로 문자 배열을 만들고, reverse()로 순서를 뒤집은 뒤, join('')으로 다시 연결해 reversed에 저장합니다. 두 문자열이 같을 때만 YES입니다.

reverse()는 배열 자체를 바꾸지만, 여기서는 split('')이 새로 만든 배열에 적용합니다. 비교 기준인 letters 문자열은 그대로 남습니다.

원본 풀이에서 유지한 점과 정리한 점

원본 TXT도 소문자 변환, 알파벳 외 문자 제거, 뒤집기 비교 순서로 풉니다. 이 접근을 그대로 유지했습니다. 알고리즘을 교체할 오류는 없으며, 역할이 드러나도록 변수명을 바꾸고 기본값을 담던 answer 변수 대신 비교 결과를 직접 반환하도록 정리했습니다. 표준 입력 처리만 함수 바깥에 추가했습니다.

대안 풀이가 맞는 이유

전처리는 문제에서 무시하라는 문자만 제거하고, 남은 알파벳의 상대적인 순서를 보존합니다. 대소문자 역시 하나의 기준으로 통일되므로, 이후에는 영문 소문자 문자열의 순서만 비교하면 됩니다.

이 문자열과 역순 문자열이 같다는 것은 모든 위치에서 왼쪽에서 읽은 문자와 오른쪽에서 읽은 문자가 같다는 뜻입니다. 따라서 같으면 회문이며, 하나라도 다르면 회문이 아닙니다. 원래 문자열 전체를 뒤집어 비교하면 공백이나 기호까지 비교 대상에 들어가므로 전처리 이후의 문자열을 사용해야 합니다.

대안 풀이: 원자료의 JavaScript 실행 코드

아래 전체 코드를 solution.cjs에 저장하고, 예제 입력을 input.txt에 넣은 뒤 node solution.cjs < input.txt로 실행하세요. 별도 패키지는 필요하지 않습니다.

const fs = require('node:fs');
const input = fs.readFileSync(0, 'utf8');
const text = input.split(/\r?\n/, 1)[0];

function solution(text) {
  const letters = text.toLowerCase().replace(/[^a-z]/g, '');
  const reversed = letters.split('').reverse().join('');
  return letters === reversed ? 'YES' : 'NO';
}

console.log(solution(text));

/\r?\n/으로 LF와 CRLF 줄바꿈을 구분하고 첫 줄만 가져옵니다. 끝에 줄바꿈이 없어도 입력 문자열은 유지됩니다. 공백 분리를 하지 않으므로 공식 예제의 문장 전체가 함수로 전달됩니다.

표준 입력을 읽는 방식은 Node.js fs.readFileSync 문서, 전체 치환과 배열 뒤집기의 동작은 MDN replace 문서와 MDN reverse 문서에서 확인했습니다. 확인일은 2026년 10월 12일입니다.

대안 풀이의 원본 예제 추적

  1. 소문자 변환 후에는 found7, time: study; yduts; emit, 7dnuof가 됩니다.
  2. 숫자 7, 공백, 쉼표, 콜론, 세미콜론을 제거하면 foundtimestudyydutsemitdnuof만 남습니다.
  3. 남은 문자열은 foundtimestudy와 그 역순인 ydutsemitdnuof가 이어진 형태입니다.
  4. 전체를 뒤집어도 같은 문자열이므로 최종 출력은 YES입니다.

공통 경계값과 대안 풀이의 복잡도

다음은 구현을 확인하려고 따로 만든 검사입니다. 원본 문제에 수록된 추가 예제가 아닙니다.

  • A: 한 글자만 남으므로 YES입니다.
  • aA와 aB: 대소문자만 다르면 YES, 실제 알파벳이 다르면 NO입니다.
  • A,b!A: 표지의 설명용 입력입니다. aba가 되어 YES입니다.
  • 1a2: 숫자를 제외하면 a만 남아 YES입니다. 숫자를 비교에 포함하는 실수를 잡을 수 있습니다.
  • a,b:c;a: abca가 되므로 NO입니다. 양끝이 같아도 안쪽이 다를 수 있습니다.
  • 동일 알파벳 100개와 길이 99·100의 대칭 문자열, 최대 길이에서 바깥쪽 또는 안쪽 문자 한 개가 달라지는 경우를 확인합니다.

원문은 최소 길이와 알파벳이 반드시 포함되는지를 명시하지 않습니다. 알파벳이 하나도 남지 않으면 원본 TXT와 이 풀이는 빈 문자열을 서로 비교하여 YES를 반환합니다. 이는 구현의 동작 확인이며, 원문에 없는 별도 입력 보장이나 공식 예제라고 보지 않습니다.

2026년 10월 12일 Node.js v24.18.0에서 위 최종 코드를 실제 실행했습니다. PDF·TXT에 공통으로 실린 원본 입력 1종과 별도로 만든 입력 19종을 각각 LF·CRLF·끝 줄바꿈 없음으로 실행한 60개 검사가 모두 예상 결과와 일치했습니다. 빈 입력과 알파벳이 남지 않는 입력은 원문의 보장 범위가 불명확한 경우로 구분하여 구현의 동작만 확인했습니다.

  • 시간 복잡도: O(n). 원문 길이 n을 기준으로 입력 읽기·소문자 변환·필터링이 선형이고, 남은 알파벳 m개에 대한 분리·뒤집기·연결·비교도 O(m)입니다. m≤n이므로 전체 O(n)입니다.
  • 공간 복잡도: O(n). 입력과 변환 문자열, 문자 배열, 역순 문자열을 보관합니다. 뒤집기 자체가 배열 내부에서 이루어져도 전체 풀이가 O(1) 공간이 되는 것은 아닙니다.

입력은 최대 100자이므로 이 선형 처리 방식으로 충분합니다. 원본 TXT의 a~z 기준을 따르는 풀이이며, 모든 언어의 문자나 화면에 보이는 글자 단위를 판별하는 범용 Unicode 회문 검사로 확장하지 않습니다.

자가 확인

  1. 소문자 변환보다 알파벳 필터링을 먼저 하면 어떤 대문자 입력에서 잘못될까요?
  2. 정규식의 g를 빼면 기호가 여러 개인 입력에 어떤 문제가 생길까요?
  3. 숫자도 비교에 포함하도록 조건이 바뀐다면 필터 범위를 어떻게 바꾸어야 할까요?
확인 기준 보기

변환 순서의 이유, 전체 치환의 필요성, 비교 대상의 범위를 각각 설명할 수 있으면 됩니다. 숫자도 포함하는 변형에서는 소문자 변환 후 a~z와 0~9를 남깁니다. 이는 원본 문제와 구별되는 변형 조건입니다.

기본 회문 비교부터 복습하려면 회문 문자열 풀이를 참고하세요. 이번 글은 전처리 기준을 추가한 별개의 문제이며, 원자료 다음 문제는 “숫자만 추출”입니다.

글 소개·학습 준비·전체 목차

숫자·공백·문장부호를 제외하고 대소문자를 구분하지 않았을 때 회문인지 판별하는 문제입니다. 첫 줄 전체를 입력받아 YES 또는 NO를 반환하는 함수를 직접 작성해 보세요. 문자열과 함수의 기본 문법을 알고 시작할 수 있습니다.

A,b!A에서 문장부호를 지우고 소문자 aba로 정리하는 파스텔 문자 타일과 오른쪽 아래 작은 갈색 BlogFlow 곰

이 글이 도움이 되었나요?

조회 중

이어서 공부하기

체크포인트: 해설을 가리고 다시 풀고, 경계 입력을 하나 바꾸어 예상 결과와 실제 결과를 비교하세요. 전처리할 문자와 비교할 문자를 구분하고 마지막 문자·마지막 묶음을 확인하세요.

다음 추천 · 문제: 숫자만 추출 풀이: 문자 사이의 숫자를 순서대로 수로 만들기

같은 주제의 문제에 적용하며 방금 배운 개념을 확인합니다.

권장 순서는 학습 가이드와 같습니다. 다른 순서는 접힌 참고 목록에서 확인할 수 있습니다. 읽음 표시는 숙달이나 채점 결과가 아닙니다.

원래 과정 목록 순서 (선택)

읽음 기록

읽음 — / 전체 57개 · 필수 57개

이 글을 쓴 해비

웹사이트를 제작·운영하고, 개인 서비스와 자동화·AI 도구를 만듭니다. 직접 만들며 배운 내용과 문제 해결 과정을 BlogFlow에 기록합니다.

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기