4

私は 2^1000 のすべての数字を合計する必要があるプロジェクト オイラーの問題 #16 を解決しようとしています。こんなに大きな数を扱うのに行き詰まりました。私のプログラムは 10^16 未満の任意の数値に対して機能しましたが、その後失敗しました。これは、私の論理が正しいことを教えてくれました。すべての変数とメソッドを BigDecimal に変換しましたが、プログラムが正しく実行されません。そのままコンパイルされ、エラーはありません。終了しないだけです。ここで私がどこで間違ったのか、誰かが考えを持っていますか?

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Powerdigitsum {

    private static final BigDecimal one = new BigDecimal("1");
    private static final BigDecimal ten = new BigDecimal("10");

    private static BigDecimal sumofDigits(BigDecimal n){

        BigDecimal sum = new BigDecimal("0");

        while(n.compareTo(one) == 1 || n.compareTo(one) == 0){

            sum.add(n.remainder(ten));

            n.divide(ten);

            n = n.setScale(0, RoundingMode.FLOOR);

        }

    return sum;

    }

    public static void main(String[] args) {

        final double the_number = Math.pow(2,1000);

        final double test = 15;

        final BigDecimal two_to_the_thousandth_power = new BigDecimal(test);

        System.out.println(sumofDigits(two_to_the_thousandth_power));

    }

}
4

8 に答える 8

6

BigInteger適切に使用してください:

BigInteger a = new BigInteger("2").pow(1000);

于 2012-12-25T10:53:29.423 に答える
3

全体の方法はちょっと間違っています。これを参照してください:

private static BigInteger sumOfDigits(BigInteger n) {
    BigInteger sum = BigInteger.ZERO;
    while (n.compareTo(BigInteger.ZERO) == 1) {
        sum = sum.add(n.remainder(ten));
        n = n.divide(ten);
    }
    return sum;
}

1 ではなく 0 と比較する必要がありました。また、BigIntegers と BigDecimals の値を割り当てる必要があります。これらのメソッドは単独では何も実行せず、これらのクラスのインスタンスは不変です。

整数の場合は、一般に を使用することをお勧めしますBigInteger。小数部分 (除算から得られる部分) は単に捨てられます。

于 2012-12-25T10:52:16.257 に答える
1
final double the_number = Math.pow(2,1000);

the_number結果を取得するのに十分な大きさではないため、これは機能しません。pow呼び出しをBigInteger次のように変換する必要があります。

BigInteger result = new BigInteger("2").pow(1000);

ただし、注意してください..これには時間がかかる場合があります..

于 2012-12-25T10:55:48.043 に答える
1

BigDecimal(double)コンストラクターは使用しないでくださいdouble。2^1000 を表すことができないプリミティブ型によって制限されます。

を使用できますBigInteger。これらの行に沿った何かが機能するはずです(おそらく最適ではありませんが...):

public static void main(final String... args)
{
    // 2^1000
    final BigInteger oneTo2000 = BigInteger.ONE.shiftLeft(1000);

    BigInteger digitSum = BigInteger.ZERO;

    // We don't want to split against the empty string, the first element would be ""
    for (final String digit: oneTo2000.toString().split("(?<=.)"))
        digitSum = digitSum.add(new BigInteger(digit));

    System.out.println(digitSum);
}
于 2012-12-25T11:01:40.480 に答える
0
import java.math.BigInteger;

public class Problem16 {
public static void main(String[] args) {

   BigInteger number2 = new BigInteger("2");   
   BigInteger number3 = new  BigInteger("0");
   number3 =number2.pow(1000);

   String str = number3.toString();
BigInteger sum = new BigInteger("0");

 for(int i=0; i<str.length(); i++)
  {
    char c= str.charAt(i); 

    int value = Character.getNumericValue(c);
    BigInteger value2 = new BigInteger(Integer.toString(value));
     sum =sum.add(value2) ; 
  }
System.out.println(sum);

}

}
于 2013-03-11T09:33:23.677 に答える
0
import java.math.BigInteger;

public class P16 {

    public static BigInteger digitSum(int n) {
        BigInteger sum = BigInteger.ZERO;
        BigInteger number = new BigInteger("2").pow(n);

        while (number.compareTo(BigInteger.ZERO) == 1) {
            BigInteger remainder = number.remainder(BigInteger.TEN);
            sum = sum.add(remainder);
            number = number.divide(BigInteger.TEN);
        }

        return sum;
    }

    public static void main(String[] args) {
        final double START = System.nanoTime();
        System.out.println(digitSum(Integer.parseInt(args[0])));
        final double DURATION = System.nanoTime() - START;
        System.out.println("Duration: " + DURATION / 1000000 + "ms.");
    }
}

BigInteger を使用せずにこの問題を解決する方法はあるかもしれませんが、BigInteger を使用するとコードの実行速度が大幅に向上することは明らかです。私は答えを見つけるのに約4msしかかかりませんでした。

于 2017-01-08T19:09:35.690 に答える