Я работаю над проблемой 29 Project Euler, в которой говорится:
Рассмотрим все целые комбинации a ^ b для 2 ≤ a ≤ 5 и 2 ≤ b ≤ 5:
2 ^ 2 = 4, 2 ^ 3 = 8, 2 ^ 4 = 16, 2 ^ 5 = 32
3 ^ 2 = 9, 3 ^ 3 = 27, 3 ^ 4 = 81, 3 ^ 5 = 243
4 ^ 2 = 16, 4 ^ 3 = 64, 4 ^ 4 = 256, 4 ^ 5 = 1024
5 ^ 2 = 25, 5 ^ 3 = 125, 5 ^ 4 = 625, 5 ^ 5 = 3125
Если они затем расположены в числовом порядке, с удаленными повторениями, мы получаем следующую последовательность из 15 различных терминов:
4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125
Сколько различных терминов содержится в последовательности, генерируемой ab для 2 ≤ a ≤ 100 и 2 ≤ b ≤ 100?
Я написал программу для решения этой проблемы на Java. он работает без ошибок, однако не дает ожидаемого результата. Я предоставил свой код и результат ниже.
import java.util.ArrayList;
import java.math.BigInteger;
public class problemTwentyNine {
public static void main(String [] args) {
long start = System.nanoTime();
ArrayList<BigInteger> distinctTerms = new ArrayList<BigInteger>();
BigInteger temp;
for(int i = 2; i <= 100; i++) {
for(int j = 2; j <= 100; j++) {
temp = new BigInteger("" + (int) (Math.pow(i, j)));
if(!distinctTerms.contains(temp)) {
distinctTerms.add(temp);
}
}
}
System.out.println(distinctTerms.size());
long stop = System.nanoTime();
System.out.println("Execution time: " + ((stop - start) / 1e+6) + "ms");
}
}
Выход:
422
Время выполнения: 24,827827 мс
После ввода этого ответа в проект euler мы видим, что он неверен; но я не вижу, где я ошибся в своем коде.
2 ответа
Причина, по которой вы получаете только 422 различных элемента, заключается в том, что ваши значения такие большие, и вы преобразуете их в int
.
Когда результат Math.pow(i, j)
(double
) больше, чем Integer.MAX_VALUE
, и вы приводите к int
, то результатом будет Integer.MAX_VALUE
.
Раздел 5.1.3 JLS охватывает это сужающее примитивное преобразование :
В противном случае один из следующих двух случаев должен быть истинным:
Значение должно быть слишком маленьким (отрицательное значение большой величины или отрицательная бесконечность), а результатом первого шага будет наименьшее представимое значение типа int или long.
Значение должно быть слишком большим (положительное значение большой величины или положительная бесконечность), а результатом первого шага будет наибольшее представимое значение типа int или long.
(курсив мой)
Вы получаете этот результат много, поэтому есть только 422 различных результата.
Измените свой расчет на математический BigInteger
.
temp = new BigInteger("" + i).pow(j);
С этим изменением у меня теперь 9 183 различных элемента. Это имеет больше смысла, поскольку некоторые степени полных квадратов будут повторяться.
Линия (int) (Math.pow(i, j))
не имеет большого смысла, поскольку 100^100
намного больше, чем Integer.MAX_VALUE
. Вы должны выполнять полномочия, используя BigInteger
.
Должен быть
temp = BigInteger.valueOf(i).pow(j);
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.