Я пытаюсь разбить цифры целого числа. Позвольте мне быть более конкретным. Я использую последовательность Фибоначчи для генерации большого целого числа, теперь используя этот алгоритм, мне нужно зациклиться до тех пор, пока не найду BigInteger, где первые 9 цифр и последние 9 цифр являются pandigital. Единственная проблема - это сумма, которую я должен зацикливать - 300K (теперь BigInteger будет настолько огромным).Разделение цифр BigIntegers
Я попытался преобразовать BigInteger в строку, а затем использовать «substring (begin, end)». Но это так медленно, потребовалось почти 28 минут, чтобы сделать 100K индексов.
Для этого есть математическое решение, но я не совсем уверен, что это такое, если бы кто-то мог привести меня в правильном направлении, это было бы оценено по достоинству. Примечание. Я не прошу ответа напрямую, просто шаг к поиску правильного ответа.
Вот мой код только в том случае, если вам интересно:
import java.math.BigInteger;
public class Main {
public static void main(String...strings)
{
long timeStart = System.currentTimeMillis();
fib(300_000);
long timeEnd = System.currentTimeMillis();
System.out.println("Finished processing, time: " + (timeEnd - timeStart) + " milliseconds.");
}
public static BigInteger fib(int n)
{
BigInteger prev1 = BigInteger.valueOf(0), prev2 = BigInteger.valueOf(1);
for (int i = 0; i < n; i++)
{
BigInteger savePrev1 = prev1;
prev1 = prev2;
prev2 = savePrev1.add(prev2);
}
return prev1;
}
static BigInteger[] pows = new BigInteger[16];
static {
for (int i = 0; i < 16; i++) {
pows[i] = BigInteger.TEN.pow(i);
}
}
static boolean isPanDigital(BigInteger n) {
if (!n.remainder(BigInteger.valueOf(9)).equals(BigInteger.ZERO)) {
return false;
}
boolean[] foundDigits = new boolean[9];
boolean isPanDigital = true;
for (int i = 1; i <= 9; i++) {
BigInteger digit = n.remainder(pows[i]).divide(pows[i - 1]);
for (int j = 0; j < foundDigits.length; j++) {
if (digit.equals(BigInteger.valueOf(j + 1)) && !foundDigits[j]) {
foundDigits[j] = true;
}
}
}
for (int i = 0; i < 9; i++) {
isPanDigital = isPanDigital && foundDigits[i];
}
return isPanDigital;
}
}
Обновлено, удалось выяснить, как генерировать первые 9 цифр (и это, кажется, не слишком медленно). Но у меня возникает проблема с получением девяти цифр.
import java.math.BigInteger;
public class Main {
public static void main(String...strings)
{
long timeStart = System.currentTimeMillis();
fib(300_000);
long timeEnd = System.currentTimeMillis();
System.out.println("Finished processing, time: " + (timeEnd - timeStart) + " milliseconds.");
}
public static BigInteger fib(int n)
{
BigInteger prev1 = BigInteger.valueOf(0), prev2 = BigInteger.valueOf(1);
for (int i = 0; i < n; i++)
{
if (prev1.toString().length() > 19)
{
String leading9Digits = leading9Digits(prev1);
if (isPanDigital(BigInteger.valueOf(Integer.valueOf(leading9Digits))))
{
System.out.println("Solved at index: " + i);
break;
}
}
BigInteger savePrev1 = prev1;
prev1 = prev2;
prev2 = savePrev1.add(prev2);
}
return prev1;
}
public static String leading9Digits(BigInteger x) {
int log10 = (x.bitLength() - 1) * 3/10;
x = x.divide(BigInteger.TEN.pow(Math.max(log10 + 1 - 9, 0)));
return x.toString().substring(0, 9);
}
static BigInteger[] pows = new BigInteger[16];
static {
for (int i = 0; i < 16; i++) {
pows[i] = BigInteger.TEN.pow(i);
}
}
static boolean isPanDigital(BigInteger n) {
if (!n.remainder(BigInteger.valueOf(9)).equals(BigInteger.ZERO)) {
return false;
}
boolean[] foundDigits = new boolean[9];
boolean isPanDigital = true;
for (int i = 1; i <= 9; i++) {
BigInteger digit = n.remainder(pows[i]).divide(pows[i - 1]);
for (int j = 0; j < foundDigits.length; j++) {
if (digit.equals(BigInteger.valueOf(j + 1)) && !foundDigits[j]) {
foundDigits[j] = true;
}
}
}
for (int i = 0; i < 9; i++) {
isPanDigital = isPanDigital && foundDigits[i];
}
return isPanDigital;
}
}
'Но это так медленно, ...' Что происходит медленно? Преобразование строк? Взятие подстроки? Или процесс расчета? –
Медленная часть принимает подстроку BigInteger, так как вы подставляете такое огромное количество. Это может занять до 6 часов, если я его подниму 300k. –
Извините, до сих пор не понимаю: 'BigInteger.toString()' или 'String.substring'. Вам нужно всего 9 символов, это не займет много времени. –