PHP: function primeFactors ($n) { for ($i = 2; $i < $n; $i++) { if (is_int ($n / $i)) { while (is_int ($n / $i)) { $n = $n / $i; $count++; } if ($n == 1) { return $str."($i)"; } elseif ($count != 1) { $str .= "($i**$count)"; } else { $str .= "($i)"; } } } return "($n)"; } Задача этой функции разобрать число (которое больше единицы) на простые множители. Например, при аргументе 7775460 должен возвращать строку "(2**2)(3**3)(5)(7)(11**2)(17)" , но у меня возвращает только "(17)". Я по алгоритму провёл число, и вроде бы всё должно быть нормально, однако нет (возможно, недоглядел). не пишите про эффективность
Я возвращаю в 9 строчки str. n возвращается, если только число не разбивается на простые множитель, то есть оно само простое
Кстати, заметил недоработку кода: он не работал бы с числами, вроде "4". Но это не относится к проблеме
Привет. Вот у тебя похоже в первом if после while надо сравнивать $count с единицей, а не $n. Я вот решил как, все работает: PHP: function primeFactors($n) { if ($n <= 1) { return $n; } $result = ''; for ($i = 2; $i <= $n; $i += 1){ $counter = 0; while ($n % $i === 0) { $counter += 1; $n /= $i; } if ($counter === 1) $result .= "($i)"; if ($counter > 1) $result .= "($i**$counter)"; } return $result; }
При твоём коде проходят все циклы, что не очень эффективно. Я сравнивал с n, чтоб как раз решить эту проблему, так как n должен ВСЕГДА становится равным 1 после разбора числа на все простые множители. Однако я до сих пор не могу понять, почему кусок кода с 8 строки до 10 не работает
Нет, цикл while будет работать только, если будет срабатывать нужное условие, когда выражение делится без остатка, он не будет работать в холостую. Что касается твоей ошибки. Вот смотри ты стравниваешь $n==1 - строка 8, а возвращаешь return$str."($i)" - строка 9. Почему ты возвращаешь просто $str."($i)" . Короче $n==1 будет равен всегда в итоге, если соблюдается while(is_int($n/$i)), и ты условием в строке 8 убиваешь возможность дойти до условия elseif($count!=1) - строка 11, скрипт до туда просто не доходит. Пойми после return на строке 9 скрипт прекращает работу!
Вот чуток изменённый велосипед: PHP: for($i = 0; $i < 100; $i++) { $N = (int) rand(4, 1000); $arr = primeFactors($N); $sResult = "(" . ($arr ? implode(")(", array_map(function($item) { return "{$item[0]}" . ($item[1] > 1 ? "**{$item[1]}" : '');}, $arr)) : $N) . ")"; echo "$N === $sResult"; echo nl2br(PHP_EOL); } function primeFactors($number) { $aResult = []; for ($i = 2, $cnt = $number >> 1; $i <= $cnt; $i++) { $exp = 0; while ($number % $i === 0) { $number = $number / $i; $exp++; } if ($exp > 0) { $aResult[] = [$i, $exp]; } } return $aResult; }
Я говорил про цикл for. Я не совсем понял твоё объяснение. N будет равно 1 только один раз и только тогда, когда нужно внести в строку последний множитель, то есть вернуть строку, заполнявшуюся до этого + присоединить невносившийся раньше в строку последний оставшийся множитель. Скрипт должен доходить до других условий, т. к n не равняется 1 --- Добавлено --- Мне нужен не новый велосипед, а объяснение, почему не работает старый
Вообщем отвардампил твой код и вот ошибки.: 1. Ты не обнуляешь счетчик $count. 2. Раз ты цикл for составляешь с условием $i<$n, то у тебя число когда доходит до последнего множителя не заходит скрипт в цикл, а ты на сроке 19 возвращаешь только $n - это только последний множитель. Тогда нужно возвращать $str .= "($n)" Вот твой код с исправленными ошибками: PHP: function primeFactors ($n) { for ($i = 2; $i < $n; $i++) { if (is_int ($n / $i)) { $count = 0; while (is_int ($n / $i)) { $n = $n / $i; $count++; } if ($n == 1) { $str . "($i)"; return $str; } elseif ($count != 1) { $str .= "($i**$count)"; } else { $str .= "($i)"; } } } return $str .= "($n)"; } var_dump(primeFactors(7775460));
PHP: function primeFactors ($n) { for ($i = 2; $i <= $n; $i++) { if (is_int ($n / $i)) { $count = 0; while (is_int ($n / $i)) { $n = $n / $i; $count++; } if ($count != 1) { $str .= "($i**$count)"; } else { $str .= "($i)"; } } } return $str == null ? "($n)" : $str; } Теперь код работает