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

JavaScript에서 십진수 변환 없이 두 이진수 문자열 더하기

문제 정의

두 개의 이진수 문자열 str1str2를 각각 첫 번째와 두 번째 인자로 받는 JavaScript 함수를 작성해야 합니다.

이 함수는 두 이진수의 합을 반환해야 하며, 단순히 이진수를 십진수로 변환한 뒤 더하는 방식은 사용할 수 없습니다. 또한 최종 결과에는 의미 없는 앞자리 0이 포함되지 않아야 합니다.

예를 들어, 함수의 입력이 다음과 같다면:

입력

const str1 = '1101';
const str2 = '10111';

출력

const output = '100100';

구현 방법

가장 효율적인 접근 방식은 우리가 손으로 이진수 덧셈을 할 때와 동일하게, 가장 낮은 자리부터 한 자리씩 더하면서 올림(carry)을 처리하는 것입니다. 다음은 이 원리를 적용한 코드입니다:

const str1 = '1101';
const str2 = '10111';

const addBinary = (str1 = '', str2 = '') => {
    // 문자열을 배열로 분리한 뒤 뒤집어 일의 자리부터 처리
    str1 = str1.split('').reverse();
    str2 = str2.split('').reverse();
    let res = '', temp = 0;

    while (str1.length || str2.length || temp) {
        // 각 자리 숫자를 더함 (배열이 비면 undefined → 0 처리)
        temp += (~~str1.shift()) + (~~str2.shift());
        let mod = temp % 2;      // 현재 자리의 값
        res = mod + res;
        temp = temp > 1;         // 올림 발생 여부
    };

    // 앞자리 0 제거, 전부 0이면 '0' 반환
    return (+res) ? res.replace(/^0+/, '') : '0';
};
console.log(addBinary(str1, str2));

코드 동작 원리

이 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다:

1. 자릿수 정렬: split('')으로 문자열을 배열로 만들고 reverse()로 뒤집으면, 일의 자리부터 차례대로 접근할 수 있습니다.

2. 자릿수별 덧셈: while 루프 안에서 shift()로 각 배열의 맨 앞 요소(현재 자리의 숫자)를 꺼내 더합니다. 이때 이중 틸드 연산자 ~~를 사용하면 배열이 이미 비어 있을 때 undefined가 아닌 0으로 처리되므로, 길이가 다른 두 문자열도 안전하게 더할 수 있습니다.

3. 올림 처리: 합계를 2로 나눈 나머지(temp % 2)가 현재 자리의 값이 되고, 합계가 2 이상이면 temptrue(즉, 1)로 설정되어 다음 자리로 올림이 전달됩니다.

4. 결과 정리: 루프가 끝난 뒤 replace(/^0+/, '')로 앞자리의 불필요한 0을 제거하고, 결과가 빈 값이 되는 경우(모든 자리가 0인 경우)에는 '0'을 반환합니다.

실행 결과

100100

1101(13) + 10111(23) = 100100(36)으로, 십진수 변환 없이 올바른 이진수 덧셈 결과가 출력되는 것을 확인할 수 있습니다.