문제 정의
(ax+b)^n 형태의 수식을 입력받아 전개하는 JavaScript 함수를 작성해야 합니다. 여기서 a와 b는 양수 또는 음수일 수 있는 정수, x는 임의의 한 글자 변수, n은 자연수입니다. 단, a가 1일 경우에는 변수 앞에 계수를 따로 표기하지 않습니다.
함수는 전개된 결과를 ax^b+cx^d+ex^f... 형태의 문자열로 반환해야 합니다. 여기서 a, c, e는 각 항의 계수이고, x는 원래 수식에 사용된 한 글자 변수 그대로이며, b, d, f는 각 항에서 x가 거듭제곱된 지수로 반드시 내림차순으로 정렬되어야 합니다.
예제 코드
다음은 위 문제를 해결하는 JavaScript 코드입니다 -
const str = '(8a+6)^4';
const trim = value => value === 1 ? '' : value === -1 ? '-' : value
const factorial = (value, total = 1) =>
value <= 1 ? total : factorial(value - 1, total * value)
const find = (str = '') => {
let [op1, coefficient, variable, op2, constant, power] = str
.match(/(\W)(\d*)(\w)(\W)(\d+)..(\d+)/)
.slice(1)
power = +power
if (!power) {
return '1'
}
if (power === 1) {
return str.match(/\((.*)\)/)[1]
}
coefficient =
op1 === '-'
? coefficient
? -coefficient
: -1
: coefficient
? +coefficient
: 1
constant = op2 === '-' ? -constant : +constant
const factorials = Array.from({ length: power + 1 }, (_, i) => factorial(i))
let result = ''
for (let i = 0, p = power; i <= power; ++i, p = power - i) {
let judge =
factorials[power] / (factorials[i] * factorials[p]) *
(coefficient * p * constant * i)
if (!judge) {
continue
}
result += p
? trim(judge) + variable + (p === 1 ? '' : `^${p}`)
: judge
result += '+'
}
return result.replace(/\+\-/g, '-').replace(/\+$/, '')
};
console.log(find(str));
출력 결과
576a^3+1152a^2+576a
코드 동작 원리
위 코드는 다음과 같은 단계로 동작합니다.
- 수식 파싱: 정규 표현식 /(\W)(\d*)(\w)(\W)(\d+)..(\d+)/를 사용해 첫 번째 부호, 계수, 변수, 두 번째 부호, 상수, 지수를 한 번에 추출합니다.
- 예외 처리: 지수가 0이면 '1'을 반환하고, 지수가 1이면 괄호 안의 원래 수식을 그대로 반환합니다.
- 부호 및 계수 처리: 앞의 부호가 '-'이면 계수를 음수로, 뒤의 부호가 '-'이면 상수를 음수로 변환합니다. 계수나 상수가 생략된 경우에는 1로 간주합니다.
- 팩토리얼 사전 계산: 재귀 방식으로 구현한 팩토리얼 함수를 이용해 0부터 n까지의 팩토리얼 값을 미리 배열로 준비합니다.
- 각 항 생성: 이항계수 n! / (i! × (n-i)!)를 활용해 각 항의 계수를 구한 뒤, 지수가 남아 있으면 변수와 '^' 지수를 붙여 결과 문자열에 누적합니다. 계수가 0인 항은 건너뛰고, 계수가 1 또는 -1일 때는 숫자 없이 부호만 표시됩니다.
- 결과 정리: 마지막으로 '+-' 패턴을 '-'로 치환하고 문자열 끝의 '+'를 제거해 깔끔한 최종 결과를 완성합니다.
예를 들어 입력이 '(8a+6)^4'라면 함수는 576a^3+1152a^2+576a를 출력합니다. 이처럼 정규 표현식 파싱, 재귀 팩토리얼, 이항계수 공식을 조합하면 외부 라이브러리 없이도 이항 표현식 전개 기능을 직접 구현할 수 있습니다.