Результат для Integer.MAX_VALUE:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315, 24678050, 24678051, 88593477, 146511208, 472335975, 534494836, 912985153]
memory 444
time = 75
Для Long.MAX_VALUE потребуется ещё больше времени. Отсюда вопрос:
Как можно "ускорить" процесс? (правильный ответ пока смотреть не хочется)
public static long[] getNumbers(long N) {
if (N <= 0) return new long[0];
// составляем матрицу степеней для каждой цифры. Максимальная степень 19 потому что в Long.MAX_VALUE 19 цифр
long [][] matrix = new long[10][20];
for (int i = 0; i < 10; i++) {
for (int j = 1; j < 20; j++) {
matrix[i][j] = (long) Math.pow(i,j);
}
}
List <Long> armstrongNumbers = new ArrayList<>();
// в цикле проверяем все числа от 1 до заданного
for (long n = 1; n < N; n++) {
int length = (int) (Math.log10(n) + 1); // количество цифр в числе
long tempn = n; // копия проверяемого числа
long sum = 0; // сумма степеней проверяемого числа
// проходим по каждой цифре проверяемого числа
while (tempn != 0) {
long num = tempn % 10; // берём правую цифру из числа
// берём значение цифры в нужной степени из матрицы
long numPow = matrix[(int)num][length];
// добавляем к общей сумме степеней проверяемого числа
sum += numPow;
// если сумма степеней уже больше, чем само число, то нет смысла возводить в степень остальные цифры
if (sum > n) break;
// сокращаем число на одну цифру справа
tempn /= 10;
}
// если сумма степеней всех цифр равна самому числу, то это число Арстронга — добавляем его в список
if (sum == n) armstrongNumbers.add(n);
}
// добавляем найденные числа Армстронга из списка в массив
long[] result = new long[armstrongNumbers.size()];
for (int i = 0; i < armstrongNumbers.size(); i++) {
result[i] = armstrongNumbers.get(i);
}
return result;
}package com.javarush.task.task20.task2025;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Алгоритмы-числа
*/
public class Solution {
public static long[] getNumbers(long N) {
if (N <= 0) return new long[0];
// составляем матрицу степеней для каждой цифры. Максимальная степень 19 потому что в Long.MAX_VALUE 19 цифр
long [][] matrix = new long[10][20];
for (int i = 0; i < 10; i++) {
for (int j = 1; j < 20; j++) {
matrix[i][j] = (long) Math.pow(i,j);
}
}
List <Long> armstrongNumbers = new ArrayList<>();
// в цикле проверяем все числа от 1 до заданного
main: for (long n = 1; n < N; n++) {
// int length = (int) (Math.log10(n) + 1); // количество цифр в числе
long nTemp = n;
int length = 0;
while (nTemp > 0) {
length++;
nTemp /= 10;
}
long tempn = n; // копия проверяемого числа
long sum = 0; // сумма степеней проверяемого числа
// проходим по каждой цифре проверяемого числа
while (tempn != 0) {
// int num = (int) tempn % 10; // при таком приведении к int начиная с n = 2149681585L больше, значение num становилось отрицательным числом и на строке "long numPow = matrix[num][length]" выдавало ошибку ArrayIndexOutOfBoundsException — Почему так происходит???
long num = tempn % 10; // берём правую цифру из числа
// берём значение цифры в нужной степени из матрицы
long numPow = matrix[(int)num][length];
// long numPow = 0;
// try {
// numPow = matrix[(int)num][length];
// } catch (ArrayIndexOutOfBoundsException e) {
// System.out.println("-------");
// System.out.println("num = " + num);
// System.out.println("length = " + length);
// System.out.println("n = " + n);
// System.out.println("-------");
// break main;
// }
// добавляем к общей сумме степеней проверяемого числа
sum += numPow;
// если сумма степеней уже больше, чем само число, то нет смысла возводить в степень остальные цифры
if (sum > n) break;
// сокращаем число на одну цифру справа
tempn /= 10;
}
// если сумма степеней всех цифр равна самому числу, то это число Арстронга — добавляем его в список
if (sum == n) armstrongNumbers.add(n);
}
// добавляем найденные числа Армстронга из списка в массив
long[] result = new long[armstrongNumbers.size()];
for (int i = 0; i < armstrongNumbers.size(); i++) {
result[i] = armstrongNumbers.get(i);
}
return result;
}
public static void main(String[] args) {
long a = System.currentTimeMillis();
// System.out.println(Arrays.toString(getNumbers(1000)));
long b = System.currentTimeMillis();
// System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (8 * 1024));
// System.out.println("time = " + (b - a) / 1000);
// a = System.currentTimeMillis();
// System.out.println(Arrays.toString(getNumbers(1000000)));
// b = System.currentTimeMillis();
// System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (8 * 1024));
// System.out.println("time = " + (b - a) / 1000);
a = System.currentTimeMillis();
System.out.println(Arrays.toString(getNumbers(Long.MAX_VALUE)));
b = System.currentTimeMillis();
System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (8 * 1024));
System.out.println("time = " + (b - a) / 1000);
// a = System.currentTimeMillis();
// System.out.println(Arrays.toString(getNumbers(2149681590L)));
// b = System.currentTimeMillis();
// System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (8 * 1024));
// System.out.println("time = " + (b - a) / 1000);
// long x = 2149681580L % 10;
// System.out.println(x);
}
}