자바(Java)

자바에서 큰 수의 팩토리얼을 계산하는 프로그램

코딩하는 욤욤이 2024. 11. 9. 01:50
반응형

팩토리얼이란?

팩토리얼은 어떤 정수 n에 대해, 1부터 n까지의 모든 양의 정수를 곱한 결과를 의미합니다. 팩토리얼은 보통 n!로 표시됩니다. 예를 들어, 5!는 다음과 같습니다:

5!=5×4×3×2×1

큰 수의 팩토리얼 계산의 어려움

작은 수의 팩토리얼은 쉽게 계산할 수 있지만, 숫자가 커지면 결과값도 매우 커지게 됩니다. 예를 들어:

  • 10!=
  • 20!=

이처럼 숫자가 커지면 자바의 기본 자료형(int나 long)으로는 표현할 수 없게 됩니다. 그래서 아주 큰 값도 처리할 수 있는 방법이 필요합니다.

큰 수의 팩토리얼을 계산하는 방법

큰 수의 팩토리얼을 계산하는 방법은 두 가지가 있습니다:

  1. BigInteger 클래스 사용하기: 자바에서는 BigInteger 클래스를 이용하여 매우 큰 정수도 다룰 수 있습니다.
  2. 배열을 사용하여 직접 계산하기: 각 자릿수를 배열에 저장해서 계산하는 방법입니다. 이 방법은 조금 더 복잡하지만 교육적인 가치가 있습니다.

두 가지 방법을 차례대로 설명드리겠습니다.


1. BigInteger 클래스 사용하기

BigInteger 클래스는 자바의 java.math 패키지에 있으며, 정수 크기의 제한 없이 큰 수를 다룰 수 있습니다.

BigInteger를 이용한 팩토리얼 계산 방법

  1. BigInteger 클래스 가져오기: java.math.BigInteger를 import합니다.
  2. 결과값 초기화: BigInteger 변수에 초기값으로 1을 설정합니다. (팩토리얼 계산은 1부터 시작하므로)
  3. 곱셈 반복: 1부터 n까지 반복하면서, 매번 결과값에 현재 숫자를 곱합니다.
  4. 결과 출력: 반복이 끝나면 팩토리얼 결과를 출력합니다.

BigInteger를 사용한 자바 코드

import java.math.BigInteger;
import java.util.Scanner;

public class FactorialBigInteger {
    public static void main(String[] args) {
        // 사용자로부터 숫자를 입력받습니다.
        Scanner scanner = new Scanner(System.in);
        System.out.print("팩토리얼을 계산할 숫자를 입력하세요: ");
        int n = scanner.nextInt();
        scanner.close();

        // BigInteger를 사용하여 결과값 초기화
        BigInteger factorial = BigInteger.ONE;

        // 팩토리얼 계산을 위한 반복문
        for (int i = 1; i <= n; i++) {
            factorial = factorial.multiply(BigInteger.valueOf(i));
        }

        // 결과 출력
        System.out.println(n + "! = " + factorial);
    }
}

코드 설명

  • BigInteger 초기화: BigInteger.ONE으로 초기화하여 1로 시작합니다.
  • 곱셈 반복문: 1부터 n까지의 정수 i에 대해 factorial에 i를 곱해 나갑니다.
    • BigInteger.valueOf(i)는 정수 i를 BigInteger로 변환해 주어 곱셈을 할 수 있게 해줍니다.
  • 결과 출력: 반복문이 끝나면 최종 결과값이 저장된 factorial을 출력합니다. 이 방법은 간단하고 효율적입니다.

2. 배열을 이용한 직접 계산 (수작업 방식)

교육적인 목적으로, BigInteger 없이 큰 팩토리얼을 계산하는 방법도 소개드리겠습니다. 이 방법은 각 자릿수를 배열에 저장하여 큰 숫자 계산을 시뮬레이션하는 방식입니다.

배열을 사용하여 팩토리얼 계산 방법

  1. 결과를 저장할 배열 초기화: 배열을 생성하여 각 자릿수를 저장합니다. 예를 들어, n!=이면 배열에 [1, 2, 0]과 같이 저장합니다.
  2. 곱셈 반복: 1부터 n까지의 숫자로 각 자릿수를 곱하고 배열에 결과를 갱신합니다.
  3. 자리 올림 처리: 곱셈 결과가 10 이상이 되면 다음 자리로 넘겨주는(자리 올림) 작업을 합니다.
  4. 결과 출력: 배열에 저장된 숫자들을 뒤집어서 출력합니다.

배열을 사용한 자바 코드

import java.util.Scanner;

public class FactorialArray {
    public static void main(String[] args) {
        // 사용자로부터 숫자를 입력받습니다.
        Scanner scanner = new Scanner(System.in);
        System.out.print("팩토리얼을 계산할 숫자를 입력하세요: ");
        int n = scanner.nextInt();
        scanner.close();

        // 배열을 사용하여 결과를 저장할 공간을 초기화합니다.
        int[] result = new int[500]; // 최대 500 자리까지 저장할 수 있는 배열
        result[0] = 1;  // 0! 또는 1!의 값은 1이므로 초기값을 1로 설정
        int resultSize = 1; // 현재 결과의 자리수

        // 2부터 n까지 곱하여 팩토리얼을 계산합니다.
        for (int i = 2; i <= n; i++) {
            resultSize = multiply(i, result, resultSize);
        }

        // 배열을 거꾸로 출력하여 팩토리얼 값 표시
        System.out.print(n + "! = ");
        for (int i = resultSize - 1; i >= 0; i--) {
            System.out.print(result[i]);
        }
        System.out.println();
    }

    // 현재 팩토리얼 결과를 숫자 x와 곱하는 메서드
    private static int multiply(int x, int[] result, int resultSize) {
        int carry = 0;

        // 현재 자릿수와 x를 곱하여 결과를 배열에 저장합니다.
        for (int i = 0; i < resultSize; i++) {
            int product = result[i] * x + carry;
            result[i] = product % 10; // 곱셈 결과의 1의 자리를 저장
            carry = product / 10; // 나머지는 자리 올림으로 저장
        }

        // 자리 올림이 있는 경우 처리하여 배열에 추가
        while (carry != 0) {
            result[resultSize] = carry % 10;
            carry = carry / 10;
            resultSize++;
        }
        return resultSize;
    }
}

코드 설명

  1. 배열 초기화: 배열 result는 최대 500자리까지 저장할 수 있도록 설정되었습니다.
  2. 곱셈 메서드 (multiply): 배열의 각 자리수에 곱셈을 적용합니다.
    • 곱셈 결과가 10 이상이면 다음 자리로 자리 올림(carry)을 합니다.
  3. 결과 출력: 결과 배열을 역순으로 출력하여 팩토리얼 값을 나타냅니다.

이 방식은 좀 더 복잡하지만 큰 수의 곱셈 과정을 깊이 이해하는 데 도움이 됩니다.


  • BigInteger 사용 방법은 간단하고 효율적이므로 실무에서 권장됩니다.
  • 배열을 사용하는 방법은 수학적인 원리를 이해하는 데 유용하며, 큰 수 계산의 내부 동작을 공부하는 데 적합합니다.

두 방법 모두 같은 결과를 제공하지만, 실제 프로그램에서는 BigInteger를 사용하는 것이 더 쉽고 빠릅니다. 설명이 도움이 되었길 바랍니다! 추가로 궁금한 점이 있으시면 언제든지 질문해 주세요!

반응형