За последние 24 часа нас посетил 22251 программист и 1029 роботов. Сейчас ищут 711 программистов ...

Возвращает не ту строку

Тема в разделе "PHP для новичков", создана пользователем roboformation, 3 сен 2020.

  1. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    PHP:
    1. function primeFactors ($n) {
    2.   for ($i = 2; $i < $n; $i++) {
    3.     if (is_int ($n / $i)) {
    4.       while (is_int ($n / $i)) {
    5.         $n = $n / $i;
    6.         $count++;
    7.       }
    8.       if ($n == 1) {
    9.         return $str."($i)";
    10.       }
    11.       elseif ($count != 1) {
    12.         $str .= "($i**$count)";
    13.       }
    14.       else {
    15.         $str .= "($i)";
    16.       }
    17.     }
    18.   }
    19.   return "($n)";
    20. }
    Задача этой функции разобрать число (которое больше единицы) на простые множители. Например, при аргументе 7775460 должен возвращать строку "(2**2)(3**3)(5)(7)(11**2)(17)" , но у меня возвращает только "(17)". Я по алгоритму провёл число, и вроде бы всё должно быть нормально, однако нет (возможно, недоглядел).




    не пишите про эффективность
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.551
    Симпатии:
    1.754
    Ну так возвращай str. А ты возвращаешь $n.
     
  3. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    Я возвращаю в 9 строчки str.
    n возвращается, если только число не разбивается на простые множитель, то есть оно само простое
     
  4. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    Кстати, заметил недоработку кода: он не работал бы с числами, вроде "4". Но это не относится к проблеме
     
  5. Grigoriy Kozheletov

    Grigoriy Kozheletov Новичок

    С нами с:
    2 сен 2020
    Сообщения:
    13
    Симпатии:
    5
    Адрес:
    г. Раменское, Московская область
    Привет. Вот у тебя похоже в первом if после while надо сравнивать $count с единицей, а не $n. Я вот решил как, все работает:
    PHP:
    1. function primeFactors($n)
    2. {
    3.     if ($n <= 1) {
    4.         return $n;
    5.     }
    6.  
    7.     $result = '';
    8.     for ($i = 2; $i <= $n; $i += 1){
    9.         $counter = 0;
    10.         while ($n % $i === 0) {
    11.             $counter += 1;
    12.             $n /= $i;
    13.         }
    14.         if ($counter === 1) $result .= "($i)";
    15.         if ($counter > 1) $result .= "($i**$counter)";
    16.     }
    17.     return $result;
    18. }
     
  6. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    При твоём коде проходят все циклы, что не очень эффективно. Я сравнивал с n, чтоб как раз решить эту проблему, так как n должен ВСЕГДА становится равным 1 после разбора числа на все простые множители. Однако я до сих пор не могу понять, почему кусок кода с 8 строки до 10 не работает
     
  7. Grigoriy Kozheletov

    Grigoriy Kozheletov Новичок

    С нами с:
    2 сен 2020
    Сообщения:
    13
    Симпатии:
    5
    Адрес:
    г. Раменское, Московская область
    Нет, цикл while будет работать только, если будет срабатывать нужное условие, когда выражение делится без остатка, он не будет работать в холостую.
    Что касается твоей ошибки. Вот смотри ты стравниваешь $n==1 - строка 8, а возвращаешь return$str."($i)" - строка 9. Почему ты возвращаешь просто $str."($i)" . Короче $n==1 будет равен всегда в итоге, если соблюдается while(is_int($n/$i)), и ты условием в строке 8 убиваешь возможность дойти до условия elseif($count!=1) - строка 11, скрипт до туда просто не доходит. Пойми после return на строке 9 скрипт прекращает работу!
     
  8. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Вот чуток изменённый велосипед:
    PHP:
    1. for($i = 0; $i < 100; $i++) {
    2.   $N = (int) rand(4, 1000);
    3.   $arr = primeFactors($N);
    4.   $sResult = "(" . ($arr ? implode(")(", array_map(function($item) { return "{$item[0]}" . ($item[1] > 1 ? "**{$item[1]}" : '');}, $arr)) : $N) . ")";
    5.   echo "$N === $sResult";
    6.   echo nl2br(PHP_EOL);
    7. }
    8.  
    9. function primeFactors($number)
    10. {
    11.     $aResult = [];
    12.     for ($i = 2, $cnt = $number >> 1; $i <= $cnt; $i++) {
    13.         $exp = 0;
    14.         while ($number % $i === 0) {
    15.             $number = $number / $i;
    16.             $exp++;
    17.         }
    18.         if ($exp > 0) {
    19.             $aResult[] = [$i, $exp];
    20.         }
    21.     }
    22.     return $aResult;
    23. }
     
    #8 Sail, 4 сен 2020
    Последнее редактирование: 4 сен 2020
  9. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    Я говорил про цикл for.





    Я не совсем понял твоё объяснение. N будет равно 1 только один раз и только тогда, когда нужно внести в строку последний множитель, то есть вернуть строку, заполнявшуюся до этого + присоединить невносившийся раньше в строку последний оставшийся множитель.
    Скрипт должен доходить до других условий, т. к n не равняется 1
    --- Добавлено ---
    Мне нужен не новый велосипед, а объяснение, почему не работает старый
     
  10. Grigoriy Kozheletov

    Grigoriy Kozheletov Новичок

    С нами с:
    2 сен 2020
    Сообщения:
    13
    Симпатии:
    5
    Адрес:
    г. Раменское, Московская область
    Вообщем отвардампил твой код и вот ошибки.:
    1. Ты не обнуляешь счетчик $count.
    2. Раз ты цикл for составляешь с условием $i<$n, то у тебя число когда доходит до последнего множителя не заходит скрипт в цикл, а ты на сроке 19 возвращаешь только $n - это только последний множитель. Тогда нужно возвращать $str .= "($n)"
    Вот твой код с исправленными ошибками:
    PHP:
    1. function primeFactors ($n) {
    2.  
    3.     for ($i = 2; $i < $n; $i++) {
    4.  
    5.         if (is_int ($n / $i)) {
    6.             $count = 0;
    7.             while (is_int ($n / $i)) {
    8.                 $n = $n / $i;
    9.                 $count++;
    10.             }
    11.             if ($n == 1) {
    12.                  $str . "($i)";
    13.                  return $str;
    14.             }
    15.  
    16.             elseif ($count != 1) {
    17.                 $str .= "($i**$count)";
    18.  
    19.             }
    20.             else {
    21.                 $str .= "($i)";
    22.             }
    23.         }
    24.     }
    25.  
    26.     return  $str .= "($n)";
    27. }
    28.  
    29. var_dump(primeFactors(7775460));
     
    roboformation и TeslaFeo нравится это.
  11. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    Спасибо. Самая большая ошибка - забыл, что n в цикле for тоже меняется
     
  12. roboformation

    roboformation Активный пользователь

    С нами с:
    30 авг 2020
    Сообщения:
    162
    Симпатии:
    40
    PHP:
    1. function primeFactors ($n) {
    2.   for ($i = 2; $i <= $n; $i++) {
    3.     if (is_int ($n / $i)) {
    4.       $count = 0;
    5.       while (is_int ($n / $i)) {
    6.         $n = $n / $i;
    7.         $count++;
    8.       }
    9.       if ($count != 1) {
    10.         $str .= "($i**$count)";
    11.       }
    12.       else {
    13.         $str .= "($i)";
    14.       }
    15.     }
    16.   }
    17.   return $str == null ? "($n)" : $str;
    18. }
    Теперь код работает