我试图计算100以下所有整数的平方根,其精度高达10000位。我已经尝试使用Newton的Big Decimal方法,它吃了很多时间。
所以现在使用Jarvis method来使用BigInteger查找平方根。(我认为这种方法涉及的计算次数较少,并且不需要维护十进制数字)。即使这样,我的代码也需要花费很多时间。下面的代码描述了计算。
public class SquareRootHackerRankJarvis {
static BigInteger limit;
static BigInteger a;
static BigInteger b;
private static BigInteger squareroot(int n, int digits, BigInteger ten,
BigInteger hundred, BigInteger five) {
limit = ten.pow(digits + 1);
a = BigInteger.valueOf(n * 5);
b = BigInteger.valueOf(5);
while (b.compareTo(limit) == -1) {
if (a.compareTo(b) != -1) {
a = a.subtract(b);
b = b.add(ten);
} else {
a = a.multiply(hundred);
b = (b.divide(ten)).multiply(hundred).add(five);
}
}
return b.divide(hundred);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int P = scanner.nextInt();
int sum = 0;
int p = 1;
BigInteger ten = BigInteger.valueOf(10);
BigInteger hundred = BigInteger.valueOf(100);
BigInteger five = BigInteger.valueOf(5);
for (int i = 1; i <= N; i++) {
if (p * p == i) {
p++;
continue;
}
BigInteger x = squareroot(i, P, ten, hundred, five);
char[] digits = x.toString().toCharArray();
for (int j = 0; j <= P - 1; j++) {
sum += Character.getNumericValue(digits[j]);
}
}
System.out.println(sum);
scanner.close();
}}
任何人都可以提供或建议正确使用BigInteger以获得最佳性能吗?
对于改进上述算法的评论也很受欢迎。
答案 0 :(得分:0)
BigInteger ten = BigInteger.valueOf(10);
BigInteger hundred = BigInteger.valueOf(100);
BigInteger five = BigInteger.valueOf(5);
应移到函数squareroot
之外,以便每次调用函数时都不会创建和初始化它们。确保在此功能中仍可访问它们。
BigInteger num;
BigInteger limit;
BigInteger a;
BigInteger b;
应该在函数之外创建,并且只应在每次函数调用时初始化。
也在行
之后b = (b.divide(ten)).multiply(hundred).add(five);
可以优化到
b = b.multiply(ten).add(five);
答案 1 :(得分:0)
除了快速计算非正方形根的多个数字之外的一个观察是,从2到100只有25个非复合数。
接下来,除了引入建议的Maciej之类的常量之外,在尾随0
&#34;之前减少5
的引入。两个操作:
static final BigInteger
ten = BigInteger.TEN,
oneHundred = BigInteger.valueOf(100),
five = BigInteger.valueOf( 5),
fourtyFive = BigInteger.valueOf( 45);
/** Computes <code>digits</code> decimal digits of <code>n</code>
* <em>ignoring</em> (decimal) scaling. */
private static BigInteger sqrtDigitsJarvis(int n, int digits) {
BigInteger
limit = ten.pow(digits + 1), // might be an instance data member
a = BigInteger.valueOf(n*5L), // la*100),
b = five; // BigInteger.valueOf(ib*10 - 45);
// flawed for limit < sqrt(5n)
while (b.compareTo(limit) < 0) {
if (0 <= a.compareTo(b)) { // each branch can be parallelised
a = a.subtract(b);
b = b.add(ten);
} else {
a = a.multiply(oneHundred);
b = b.multiply(ten).subtract(fourtyFive);
}
}
return b.divide(oneHundred);
}