3

在这里和谷歌搜索了几天,并询问了我的编程朋友。不幸的是,我仍然不明白如何更改我的代码......

我的程序计算给定数字的阶乘。然后它提供一个数字,表示阶乘答案包括多少位数。然后它将这些数字的值相加得出总数。

我的程序适用于 1 之间的任何数字!和 31 !...如果你放任何超过 31 的东西!(例如 50!或 100!)它不起作用,只是返回负数而不是总数。

我希望你们能指出我正确的方向或给我一些建议。我了解使用 BigIntegers 可能是一个解决方案,但我个人并不了解它们,因此来到这里。

任何帮助将非常感激。谢谢。

    package java20;

    /**
    * Program to calculate the factorial of a given number.
    * Once implemented, it will calculate how many digits the answer includes.
    * It will then sum these digits together to provide a total.
     * @author shardy
     * date: 30/09/2012
     */

    //import java.math.BigInteger;
    public class Java20 {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {

    //Using given number stored in factorialNo, calculates factorial
    //currently only works for numbers between 1! and 31! :(
        int fact= 1;
        int factorialNo = 10;

        for (int i = 1; i <= factorialNo; i++)
            {
               fact=fact*i;
            }

        System.out.println("The factorial of " + factorialNo + 
                " (or " + factorialNo + "!) is: " + fact);

        //Using answer stored in fact, calculates how many digits the answer has
        final int answerNo = fact;
        final int digits = 1 + (int)Math.floor(Math.log10(answerNo));

        System.out.println("The number of digits in the factorials "
                + "answer is: " + digits);        

        //Using remainders, calculates each digits value and sums them together
        int number = fact;
        int reminder;
        int sum = 0;

        while(number>=1)
            {
             reminder=number%10; 
             sum=sum+reminder;
             number=number/10;
            }

        System.out.println("The total sum of all the " + digits 
                + " idividual digits from the answer of the factorial of " 
                + factorialNo + " is: " + sum);

      }
    }
4

3 回答 3

3

你可以在 java 中使用 BigInteger,它有你想要的尽可能多的数字

    BigInteger fact= BigInteger.ONE;
    int factorialNo = 10;

    for (int i = 2; i <= factorialNo; i++){
      fact = fact.multiply(new BigInteger(String.valueOf(i)));
    }

    System.out.println("The factorial of " + factorialNo +
                                " (or " + factorialNo + "!) is: " + fact);
   final int digits = fact.toString().length();

   BigInteger number = new BigInteger(fact.toString());
   BigInteger reminder;
   BigInteger sum = BigInteger.ZERO;
   BigInteger ten = new BigInteger(String.valueOf(10));

   while(number.compareTo(BigInteger.ONE)>=0)
     {
     reminder=number.mod(ten);
     sum=sum.add(reminder);
     number=number.divide(ten);
     }

     System.out.println("The total sum of all the " + digits
                     + " idividual digits from the answer of the factorial of "
                     + factorialNo + " is: " + sum

编辑:代码经过改进以与作者的代码兼容

于 2012-09-30T13:02:59.533 回答
1

如果你把任何超过 31 的东西放进去!(例如 50!或 100!)它不起作用,只是返回负数而不是总数。

这是因为当您超过它们的最大可能值时,原始整数类型会溢出。哪些计算阶乘倾向于做。

我希望你们能指出我正确的方向或给我一些建议。我了解使用 BigIntegers 可能是一个解决方案,但我个人并不了解它们,因此来到这里。

您是正确的,使用BigInteger是一种可能的解决方案。例如,您可以执行以下操作:

public BigInteger factorial(int num) {
    if (num < 0) {
        throw new IllegalArgumentException("Not today!");
    }

    BigInteger result = BigInteger.ONE;

    for (int next = 2; next <= num; next++) {
        result = result.multiply(new BigInteger(Integer.toString(next, 10)));
    }

    return result;
}
于 2012-09-30T13:08:53.357 回答
0

如果您要计算 (m!/n!) 之类的东西,最好使用阶乘的对数。

您还应该考虑以下两项改进:

  1. 记住,不要重新计算。计算后存储这些来之不易的值。
  2. 您应该使用gamma 函数来计算阶乘。您使用循环执行此操作的方式是呈现给学生的天真事物。ln(gamma(x))Numerical Recipes中有一个很好的实现。

如果必须,您始终可以使用 BigDecimal,但这是最后的手段。你仍然应该考虑这些点。

Apache Commons提供了一个 gamma 函数实现。源代码可能不像幼稚的方法那样熟悉,但如果你看到它是如何完成的,很明显即使对于温和的论点它也更有效。

于 2012-09-30T13:03:43.657 回答