Вроде код рабочий, но нет. Бесконечное выполнение
Написан метод, который принимает число, и возвращает его мультипликативную стойкость.
То есть количество раз, которое вы должны умножить на num, пока не получите одну цифру.
Например:
999 --> 4 (потому-что 9*9*9 = 729, 7*2*9 = 126, 1*2*6 = 12, и 1*2 = 2)
Вот сам код:
public static int persistence(long n) {
int count = 0;
String ss = Long.toString(n);
char[] help = ss.toCharArray();
while (n / 10 != 0) {
int qq = 1;
for (int i = 0; i < help.length; i++) {
qq = qq * help[i];
}
n = qq;
count++;
}
return count;
}
Ответы (3 шт):
Как правильно заметили в комментариях, массив help не обновляется. Получение его, как и получение строки ss из числа, нужно внести внутрь цикла while.
Однако это не единственная проблема. В строке
qq = qq * help[i];
вы перемножаете не цифры, а их коды, так как help - это массив типа char, а цифра с точки зрения char является обыкновенным символом, имеющим свой код. Для нуля, например, это 48, для девяти - 57. Так что перемножать именно цифры можно если, например, из help[i] вычитать 48. С учётом приведённых выше замечаний получим:
public static int persistence(long n) {
int count = 0;
while (n / 10 != 0) {
String ss = Long.toString(n);
char[] help = ss.toCharArray();
int qq = 1;
for (int i = 0; i < help.length; ++i) {
qq = qq * (help[i] - 48);
}
n = qq;
count++;
}
return count;
}
С использованием Stream API, код можно улучшить следующим образом (как один из вариантов):
public static int improvedPersistence(long n) {
int count = 0;
while (n > 10) {
n = String.valueOf(n)
.chars()
.mapToLong(symbol -> symbol - 48)
.reduce(1, (a, b) -> a * b);
count++;
}
return count;
}
Как было отмечено в комментариях, содержимое строки help не меняется, но также есть проблема в умножении не цифр, а их ASCII-кодов: qq = qq * help[i];, так что перемножаться будут не 1, 2, ... 9, а '1', '2', ... '9'.
Для получения цифрового значения можно использовать метод Character::getNumericValue. Также при обнаружении первого 0 можно прекращать вычисления:
public static int persistence(long n) {
int count = 0;
String s;
while ((s = Long.toString(n)).length() > 1) {
int p = 1;
for (char c : s.toCharArray()) {
int d = Character.getNumericValue(c);
p *= d;
if (d == 0) break;
}
n = p;
count++;
}
return count;
}
Или же вместо вложенного цикла и работы со строками можно воспользоваться рекурсией:
public static int persistence(long n) {
if (n < 10) {
return 0;
}
int p = 1;
while (n > 0 && p != 0) {
p *= n % 10;
n /= 10;
}
return 1 + persistence(p);
}
Потому что код сложный: два цикла, числа, строки, коды символов.
Так проще:
если n < 10 то persistance(n) = 0
иначе persistance(n) = 1 + persistance(digital_product(n))
Для digital_product нужна математика: n % 10 - младшая цифра числа, n / 10 - остальные цифры:
если n < 10 то digital_product(n) = n
иначе digital_product(n) = digital_product(n / 10) * (n % 10)
Код, в котором почти невозможно сделать ошибку, потому что нет всех лишних мелочей отвлекающих от собственно вычисления:
public static int persistence(long n) {
if (n < 10) {
return 0;
}
return 1 + persistence(digital_product(n));
}
public static long digital_product(long n) {
if (n < 10) {
return n;
}
return digital_product(n / 10) * (n % 10);
}