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

JavaScript에서 문자열이 덧셈 수열(Additive Sequence)을 이루는지 확인하는 방법


덧셈 수열(Additive Number)이란?

덧셈 수열이란 숫자로만 구성된 문자열의 자릿수들을 적절히 분할했을 때, 각 숫자가 덧셈 관계를 만족하는 시퀀스를 형성할 수 있는 문자열을 의미합니다.

유효한 덧셈 수열이 되려면 최소 세 개의 숫자를 포함해야 하며, 첫 번째와 두 번째 숫자를 제외한 나머지 모든 숫자는 반드시 바로 앞에 있는 두 숫자의 합과 일치해야 합니다. 즉, '0'부터 '9'까지의 숫자만 포함된 문자열이 주어졌을 때, 이 문자열이 덧셈 수열에 해당하는지 판별하는 함수를 작성하는 것이 목표입니다.

주의: 덧셈 수열을 이루는 각 숫자는 선행 0(leading zero)을 가질 수 없습니다. 따라서 1, 2, 03 또는 1, 02, 3과 같은 수열은 유효하지 않은 것으로 간주됩니다.

예시

문자열 "199100199"는 덧셈 수열입니다. 이 문자열은 다음과 같은 수열로 분해할 수 있습니다: 1, 99, 100, 199

1 + 99 = 100, 99 + 100 = 199

반면 "112358" 역시 1, 1, 2, 3, 5, 8로 분해되는 유효한 덧셈 수열이지만, "1023"처럼 어떻게 분할하더라도 조건을 만족하지 못하거나 선행 0 문제가 발생하는 문자열은 덧셈 수열이 아닙니다.

구현 코드

이를 판별하는 코드는 다음과 같습니다.

const str = "199100199";
const isAdditiveNumber = (numStr) => {
    if(numStr.length < 3) return false;
    let str = "";
    let seen = true;
    for(let i = numStr.length − 1; i > 1; i−−){
        str = `${numStr[i]}${str}`;
        if(numStr[i] === "0") continue;
        let s = str;
        let s2 = numStr[i − 1]
        for(let j = i − 2; j >= 0; j−−){
            if(`${s2}`.startsWith("0") && s2.length > 1){
                s2 = `${numStr[j]}${s2}` seen = false;
            } else if(parseInt(s) >= parseInt(s2)){
                let diff = s − s2;
                if(numStr.slice(0, j + 1).endsWith(diff)){
                    s = s2;
                    s2 = diff;
                    let ind = Math.floor(Math.log10(diff));
                    ind = ind < 0 ? 0 : ind
                    j −= ind;
                    seen = true;
                }else {
                    s2 = `${numStr[j]}${s2}`
                    seen = false;
                }
            }else{
                seen = false;
                break;
            }
        }
        if(seen) return seen;
    };
    return seen;
};
console.log(isAdditiveNumber(str));

동작 원리

이 알고리즘은 문자열의 끝에서부터 앞쪽으로 탐색하며 마지막 숫자 후보를 하나씩 확장해 나갑니다. 그다음 그 앞에 위치한 숫자들을 조합하여 두 번째 숫자 후보를 만들고, 두 수의 차이(diff)가 남은 접두사 문자열의 끝부분과 정확히 일치하는지 검사합니다.

검사 과정에서 두 번째 숫자 후보가 선행 0으로 시작하면 해당 경우는 무효로 처리되며, 차이값이 일치하면 두 수를 한 단계 앞으로 이동시켜 같은 과정을 반복합니다. 문자열 길이가 3 미만일 경우에는 처음부터 false를 반환하여 유효한 수열이 성립할 수 없음을 빠르게 처리합니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

true