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

EDIT : コードは、作成者のコードと互換性があるように改善されています

于 2012-09-30T13:02:59.533 に答える
1

何を入れても31以上!(たとえば、50! または 100!) は機能せず、マイナスの数値が返され、合計は返されません。

これは、可能な最大値を超えると、プリミティブ整数型がオーバーフローする可能性があるためです。どの計算階乗がそうする傾向があるか。

皆さんが私を正しい方向に向けたり、アドバイスをくれたりしてくれることを願っていました。BigIntegers の使用が解決策になる可能性があることは理解していますが、個人的には理解していないため、ここに来ました。

BigInteger使用が1つの可能な解決策であることは正しいです。たとえば、次のようなことができます。

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!) などを計算する場合は、階乗の対数を使用することをお勧めします。

次の 2 つの改善点も考慮する必要があります。

  1. メモし、再計算しないでください。計算したら、苦労して得た値を保存します。
  2. 階乗を計算するには、ガンマ関数を使用する必要があります。ループでそれを行う方法は、学生に提示される単純なことです。Numerical Recipesln(gamma(x))の優れた実装があります。

必要に応じていつでも BigDecimal を使用できますが、これは最後の手段です。これらの点を引き続き考慮する必要があります。

Apache Commonsから入手できるガンマ関数の実装があります。ソース コードは単純なアプローチほど馴染みがないかもしれませんが、それがどのように行われるかを見れば、中程度の引数であってもより効率的であることは明らかです。

于 2012-09-30T13:03:43.657 に答える