Реализовал Алгоритм из статьи, числа все находятся для Long.Max_VALUE , но за 13 секунд. Функция Arm проверяет принадлежность к числу Aрмстронга.
Помогите как оптимизировать код, чтобы программа быстрее работала? (4 пункт только не работает)
package com.javarush.task.task20.task2025;
import java.util.Arrays;
import java.util.*;
/*
Алгоритмы-числа
*/
public class Solution {
public static long[][] maspow = new long[20][10];
static {
for (int i = 1; i <= 19; i++) {
for (int j = 0; j <= 9; j++) {
if (i == 1) {
maspow[i][j] = j;
} else {
maspow[i][j] = maspow[1][j] * maspow[i - 1][j];
}
}
}
}
public static int dlinachisla(long N) {
long p = 10;
for (int i = 1; i < 19; i++) {
if (N < p) {
return i;
}
p *= 10;
}
return 19;
}
public static long Arm(int[] mas) {
int k = 0;
long h = 0;
long f = 0;
int lmas = mas.length;
for (int i = 0; i < lmas; i++) {
if (mas[i] == 0) {
k++;
h += maspow[lmas][mas[i]];
} else {
h += maspow[lmas][mas[i]];
}
}
if (h > 0 & (dlinachisla(h) <= lmas)) {
if (k == 0) {
if (dlinachisla(h) == lmas) {
int r4 = (int) (h % 10);
long l = 1;
for (int i = 2; i < lmas; i++) {
l = l * 10;
f += maspow[lmas][(int) ((h / l) % (10))];
}
int r1 = (int) (h / (10 * l));
f = f + maspow[lmas][r1] + maspow[lmas][r4];
if (h == f) {
return h;
} else {
return 0;
}
} else {
return 0;
}
} else {
for (int j = 0; j <= k; j++) {
h = 0;
f = 0;
int[] mas1 = new int[lmas - j];
int mas1l = mas1.length;
for (int i = lmas - 1; i >= j; i--) {
mas1[i - j] = mas[i];
h += maspow[lmas - j][mas1[i - j]];
}
if ((dlinachisla(h)) == mas1l) {
int r4 = (int) (h % 10);
long l = 1;
for (int i = 2; i <= mas1l; i++) {
l = l * 10;
f += maspow[mas1l][(int) ((h / l) % (10))];
}
f = f + maspow[mas1l][r4];
if (h == f) {
return h;
}
}
}
}
}
return 0;
}
public static long[] getNumbers(long N) {
if ((N > 0) && (N <= Long.MAX_VALUE)) {
int n = dlinachisla(N);
int[] mas = new int[n];
TreeSet<Long> ts = new TreeSet<Long>();
for (int i = 0; i < n; i++) {
mas[i] = 9;
}
int r = 0;
int ii = 1;
while (mas[n - 1] != 0) {
long p = Arm(mas);
if (p != 0 && p < N) {
ts.add(p);
}
if (mas[r] == 0) {
if (r + 1 == ii) {
if ((mas[ii] == 0) && (ii != n - 1)) {
ii++;
mas[ii]--;
for (int i = 0; i < ii; i++) {
mas[i] = mas[ii];
r = 0;
}
} else if ((mas[ii] == 0) && (ii == n - 1)) {
break;
} else if ((mas[ii] != 0)) {
mas[ii]--;
for (int i = 0; i < ii; i++) {
mas[i] = mas[ii];
r = 0;
}
}
} else {
r++;
if (mas[r] != 0) {
mas[r]--;
for (int i = 0; i < r; i++) {
mas[i] = mas[r];
}
r = 0;
}
}
} else {
mas[r]--;
}
}
long[] result1 = new long[ts.size()];
int u = 0;
for (long m : ts) {
result1[u] = m;
u++;
}
return result1;
} else {
return new long[0];
}
}
public static void main(String[] args) {
long a = System.currentTimeMillis();
System.out.println(Arrays.toString(getNumbers(Long.MAX_VALUE)));
long b = System.currentTimeMillis();
System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024));
System.out.println("time = " + (b - a) / 1000);
a = System.currentTimeMillis();
System.out.println(Arrays.toString(getNumbers(100000000)));
b = System.currentTimeMillis();
System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024));
System.out.println("time = " + (b - a) / 1000);
}
}