За последние 24 часа нас посетили 12595 программистов и 1014 роботов. Сейчас ищет 371 программист ...

Туплю жутко или просто не понимаю рекурсию

Тема в разделе "PHP для новичков", создана пользователем Познающий php, 22 сен 2017.

  1. Познающий php

    Познающий php Новичок

    С нами с:
    23 мар 2017
    Сообщения:
    381
    Симпатии:
    74
    В общем рекурсию предпочитаю обходить стороной если не припечет, но тут идеально вместо оверкода, но не понимаю почему не реализуется моя логика. В общем в классе есть два метода, кроме прочих
    PHP:
    1.     public function setText($text, $font){
    2.         ...
    3.         if($this->createBlocks(100)){
    4.             print "БЛОКИ СОЗДАЛИСЬ\n";
    5.             return true;
    6.         }
    7.         else {
    8.             print "Ошибка создания блоков с текстом\n";
    9.             return false;
    10.         }
    11.     }
    12.  
    13.     private function createBlocks($size){
    14.         print "КРЕАТЕ БЛОКС ЗАПУЩЕН\n";
    15.         if ($this->getBlocksWithText($this->text, $size, $this->drawText) && $this->checkSizeBlocks($size)){
    16.             print "КРЕАТЕ БЛОКС ВОЗВРАЩАЕТ ТРУ\n";
    17.             return true;
    18.         }
    19.         elseif ($size < 35) {
    20.             print "размер меньше 35\n";
    21.             return false;
    22.         }
    23.         else {
    24.             $this->textBlocks = array();
    25.             $size = round($size*0.9);
    26.             print "\n$size\n";
    27.             $this->createBlocks($size);
    28.         }
    29.     }
    Выводит в браузер такое:
    Вот эта функция createBlocks проходит первый раз входит в else вызывает сама себя и в итоге возвращает ТРУ после второго прохода. Но в первом методе так не думаают и конструкция идет в else. Почему? Я чет не понимаю?

    В общем то все работает, просто TRUE из рекурсии почему-то не засчитывается как TRUE и уходит в ELSE :confused:

    Принты расставлены для проверок :D
     
  2. Познающий php

    Познающий php Новичок

    С нами с:
    23 мар 2017
    Сообщения:
    381
    Симпатии:
    74
    Всего лишь надо было поставить return перед новым вызовом рекурсивной функции. Спасибо за помощь. тему клоз :D
     
  3. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.415
    Симпатии:
    1.767
    рекурсия очень простая штука. ты молодец, что осилил, а не забил.
     
  4. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    а я каждый раз когда приходится деревья обходить - туплю))
    вроде и не сложно)) но в тоже время сидишь тупишь)
     
  5. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    а еще помню свою первую рекурсию на пхп)) я ее с помощью goto реализовал))) :confused:
     
  6. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.162
    Симпатии:
    1.770
    Адрес:
    :сердА
    Я где-то на форуме уже выкладывал универсальный обходчик, который напильником под любые нужды точится.. Но сейчас не найду, увы. Так или иначе, он с нуля всегда пишется за две минуты. Ну или просто мне часто приходится с этим сталкиваться..
     
  7. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    я за прошедший год пару раз использовал рекурсию)) как то не было нужны в большом количестве деревьев)
    один раз зимой))
    второй раз вот сегодня)) на входе плохоский массив (id, pid, name)
    надо получить все дочерние элементы у элемента id)
    PHP:
    1.     private function calculateChilds($pid, $tree) {
    2.         static $tmp = array();
    3.         foreach($tree as $k=>$v){
    4.             if($v['pid'] == $pid){
    5.                 $tmp[] = $v['id'];
    6.                 unset($tree[$k]);
    7.                 $this->calculateChilds($v['id'], $tree);
    8.             }
    9.         }
    10.         return $tmp;
    11.     }
    --- Добавлено ---
    а вот дерево строю из того же массива))
    PHP:
    1.     private function buildTreeTypes($types, $pid) {
    2.         $tree = array();
    3.         foreach ($types as $k => $t) {
    4.             if ($t['pid'] == $pid && $k != $t['pid']) {
    5.                 unset($types[$k]);
    6.                 $tree[$k] = array(
    7.                     'id' => $t['id'],
    8.                     'pid' => $t['pid'],
    9.                     'title' => $t['title'],
    10.                     'icon' => $t['icon'],
    11.                     'child' => $this->buildTreeTypes($types, $k),
    12.                 );
    13.             }
    14.         }
    15.         return $tree;
    16.     }
    --- Добавлено ---
    а вот тоже дерево строю но уже li списком

    PHP:
    1.     /**
    2.      * Строим ul li дерево
    3.      * @param array $tree - дерево типов профиля
    4.      * @param string $name - name checkbox
    5.      * @param array $checkeds - массив с установленными галочками
    6.      * @return string
    7.      */
    8.     public function userTypeTree($tree, $name, $checkeds) {
    9.         if (is_array($tree))
    10.             $string = "<ul>";
    11.         foreach ($tree as $v) {
    12.             $is_checked = in_array($v['id'], $checkeds);
    13.             $is_pid0 = empty($v['pid']) ? 'class="jstree1_root"' : '';
    14.             $string .= "<li {$is_pid0} id=\"type{$v['id']}\">";
    15.             $string .= '<label>' . html_checkbox($name . '[' . $v['id'] . ']', $is_checked, $v['id']) . ' <span>' . $v['title'] . '</span></label>';
    16.             if (!empty($v['child'])) {
    17.                 $string .= $this->userTypeTree($v['child'], $name, $checkeds);
    18.             }
    19.             $string .= "</li>";
    20.         }
    21.         $string .= "</ul>";
    22.         return $string;
    23.     }