|
|
|
|
<?php
function recurs($b=10)
{
$h=0;
if($b==0) return;
echo "text<br>";
recurs($b-1);
for($a=0;$a<5;$a++) $h++;
echo $h;
}
recurs();
?>
|
Результат: 10 раз подряд выводит строку "text<br>", а потом 10 раз подряд выводит 5 - результат цикла.
Я уже так долго парюсь с этой рекурсией.И никак не могу понять почему именно такой результат.
Я бы понял если б оно 10 раз сначало вывело строку text а потом один раз 5, или после каждой строки text выводило бы 5, но блин почему именно так?? | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 12:21)
| | а так
<?php
function recurs($b)
{
$h=0;
if($b==0) return;
echo "text<br>";
for($a=0;$a<5;$a++) $h++;
echo $h;
recurs($b-1);
}
$b=10;
recurs($b);
?>
|
| |
|
|
|
|
|
|
|
для: Valick
(27.02.2012 в 12:34)
| | Что-то не доганяю, это тот же код только слегка изменен.
Ну вот мои размышления как оно работает:
-Обьявляется функция под именем recurs с аргументом $b
-В теле функции сначало переменной $h присваивается 0
-потом идет условие , если $b равно 0, то завершить выполнение функции(пока что у нас $b не равно 0) тобиш выполняется оператор echo
-потом идет хитрость, вызывается сама же функция но ее аргумент декрементируется а значит во вложеной функции $b уже будет 9, опят проверяется уловие и.т д.
-ну и так до самого конца пока не будет 0, а если уже 0, то выполнится return и рекурсия оборвется.
-Потом, после обрыва в теле функции ведь еще остался цикл оно его и выполняет и выводит его результат.
Но чете тут не так, мои россуждения не совпадают с результатом.
поправьте меня пож. где я россуждаю не правильно? | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 12:46)
| | >поправьте меня пож. где я россуждаю не правильно?
Вы императивно рассуждаете, нужно плясать от рекурсии (поглядите картинку ниже). Вы сначала погружаетесь на 10 позиций вниз по рекурсии, потом срабатывает точка возврата b == 0 и вы начинаете подъем из рекурсии, пока не выйдете наружу. Вычислять данные можно как на спуске, так и на подъеме, иногда только на спуске вычисляют, т.е. операторы расположены ДО рекурсивного вызова, иногда на подъеме вычисляют, т.е. операторы расположены ПОСЛЕ рекурсивного вызова. У вас они расположены и на спуске и на подъеме "text" выводится на спуске, а 5 на подъеме (поглядите рисунок, который я нарисовал вам). | |
|
|
|
|
|
|
|
для: cheops
(27.02.2012 в 12:51)
| | <?php
function recurs($b=10)
{
$h=0;
if($b==0) return;
echo "text<br>";
recurs($b-1);
for($a=0;$a<5;$a++) $h++;
echo $h;
}
recurs();
?>
А кусок кода после recurs($b-1) тоже попадает во вложеную функцию, тоесть в теле вложеной фукнции все тоже самое что и в основной? | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 13:49)
| | Да, конечно. Посмотрите на рисунок и от цифр проведите горизонтальные ломтики - это и будут функции, каждая из них содержит echo "text" и каждая из них содержит echo 5. Более того каждая функция получает управление два раза, на спуске и на подъеме. | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 12:21)
| | так все и должно быть
функция вызывает сама себя получается вложенность, но после вызова она не прерывается а возвращает 10 окончаний самой же себя, отсюда и пятерки в конце
___
и рекурсия оборвется
нет не оборвется, она вернется в саму себя, на уровень выше и только с самого верхнего уровня оборвется
я просто сначала не понял, что вы хотите от кода | |
|
|
|
|
 29.7 Кб |
|
|
для: demonow
(27.02.2012 в 12:21)
| | Гляньте рисунок во вложении.
PS Рекурсия сложно понимается вами, так как она не из императивных языков. Программисты, использующие императивные языки от неё обычно в осадок выпадают :))), даже вы не удержались, чтобы цикл for добавить, точку опоры :))) хотя есть языки, где циклов вообще нет и вот этот бы for вам пришлось бы еще одной рекурсией реализовывать :))) | |
|
|
|
|
|
|
|
для: cheops
(27.02.2012 в 12:41)
| | Спасибо, буду розбиратся. | |
|
|
|
|
|
|
|
для: cheops
(27.02.2012 в 12:41)
| | Это как циклов нет, что ж там за программисты сидят, мозговое зверье чтоль, как без них жить то можно))))?? | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 13:43)
| | Мозг, кстати, у вас все циклические задачи именно через рекурсию делает и судя по вашим вопросам прекрасно себя чувствует :))) Более того, есть языки, где нет переменных, т.е. ячеек памяти и связанных с ними именем, вернее переменные есть, но они математические, т.е. выражение вида x = x + 2 не имеет смысла, так как с точки зрения математики истинным является x = x. В таких условиях вам циклы так и так не нужны, что вы с ними будете делать, если у вас переменных нет?
Тут очень просто, вы наверное заметили, что параллельные вычисления мягко говоря набирают обороты, чипы содержат несколько ядер, видео-карты по несколько сотен параллельных обрабатывающих блоков, сеть опять же с кучей машин, которых бы надо заставить решать нужную вам задачу, а не пытаться втиснуть её в дорогущий сервер. В таких условиях именованная память становится узким местом - множеству параллельных потоков нужно около неё синхронизироваться, фактически ждать друг друга, чтобы получить доступ к телу. А если у вас нет переменных в классическом компьютерном смысле слова, то ждать нечего, знай решай задачу сотнями процессоров параллельно, а то и вообще в разных углах сети... другое дело, что составить такую программу придется на языке, который с императивным языком (C, Java, Pascal, PHP) имеет мало общего.
PS Мы сейчас примерно об этом новую книгу пишем (скажем так введение в эту область). | |
|
|
|
|
|
|
|
для: cheops
(27.02.2012 в 13:58)
| | Вообщем помозговав немного мое представление о данном коде остановилось на такой интерпретации:
В теле функции сначало выводится echo потом обращение к функции самой на себя там тоже сначало выводится echo и т.д, но код то с циклом никуда не девается(как выяснилось выше), но так получается что он не успевает выполнится зарание, его опережает вызов функции, который выводит строку "text", и получается цикл как хвост тянется в самом конце после всех выводов текста.
Надеюсь мои мысли выражены понятно.Для меня главное понять как оно работает. | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 23:35)
| | нет непонятно :) | |
|
|
|
|
|
|
|
для: Valick
(27.02.2012 в 23:38)
| | Черт)))
Ща попробую так
-Обьявляется функция под именем recurs с аргументом $b
-В теле функции сначало переменной $h присваивается 0
-потом идет условие , если $b равно 0, то завершить выполнение функции(пока что у нас $b не равно 0) тобиш выполняется оператор echo
-потом идет хитрость, вызывается сама же функция но ее аргумент декрементируется а значит во вложеной функции $b уже будет 9, опят проверяется уловие и.т д.
<?php
function recurs($b=10)
{
$h=0;
if($b==0) return;
echo "text<br>";
recurs($b-1);
for($a=0;$a<5;$a++) $h++;
echo $h;
}
recurs();
?>
|
сначало идет обращение к функции, там рекурсия, а код с циклом выполняется после, как будто цикл гонится за echo "text".
Черт, такие даунские аналогии, но мне оно почему-то так представилось.
То как рекурсия опускается я понял, но почему-то не представляется как она поднимается. | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 23:38)
| | Черт)))
не я белый и пушистый :))
просто поймите каждый возврат из функции возвращается на строчку ниже вызова самой функции
а рекурсия делает с столько копий функции самой себя, сколько позволяет логика скрипта
и из последней вложенной функции возврат не может произойти в основной скрипт, возврат происходит в предыдущую копию этой функции, где и выполняется остаток функции и так до самого верха
грубо говоря спускаясь вниз с 10 этажа на первый нужно проверить закрыта ли дверь на этаже и вымыть пол на лестничной клетке, но пережде чем вымыть пол нужно проверить закрыта ли дверь этажом ниже и так до первого этажа где двери вообще нет..
проверили? только, вы не сможете попасть обратно сразу на 10, вам придется подниматься и мыть полы на каждом этаже :) | |
|
|
|
|
|
|
|
для: Valick
(27.02.2012 в 23:52)
| | но ведь, функция будет возвращатся на этаж вверх если будет выполнятся условия $b=0; так ведь, так что получается это выражения ($b=0)тянется до самого верха пока не вернет в основную программу? | |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 23:56)
| | угу, а с чего ему быть другим? вы ведь только отнимаете по единице | |
|
|
|
|
|
|
|
для: Valick
(28.02.2012 в 00:02)
| | Тоесть когда $b==0, то это касается всех $b в каждой копии выше поэтому они возвращаются и выполняется цикл, так чтоль? | |
|
|
|
|
 21.1 Кб |
|
|
для: demonow
(27.02.2012 в 23:38)
| | Может вам на моем рисунке понятнее будет? На нем каждый прямоугольник - это функция. Я только глубину сократил, не стал все 10 рисовать. | |
|
|
|
|
|
|
|
для: Sfinks
(28.02.2012 в 00:08)
| | Ну да, я где-то так и думал просто проблема была с пониманием обратного хода функции. | |
|
|
|
|
|
|
|
для: demonow
(28.02.2012 в 00:15)
| | А вы вот так код запишите. Он не вызывает затруднений? Вот рекурсия тоже самое, только функция не 10 раз повторяется, а записывается кратко.
<?php
function recurs($b=10)
{
$h=0;
if($b==0) return;
echo "text<br>";
recurs1($b-1);
for($a=0;$a<5;$a++) $h++;
echo $h;
}
function recurs1($b)
{
$h=0;
if($b==0) return;
echo "text<br>";
recurs2($b-1);
for($a=0;$a<5;$a++) $h++;
echo $h;
}
...
function recurs8($b)
{
$h=0;
if($b==0) return;
echo "text<br>";
recurs9($b-1);
for($a=0;$a<5;$a++) $h++;
echo $h;
}
function recurs9($b)
{
$h=0;
if($b==0) return;
}
recurs();
?>
|
| |
|
|
|
|
|
|
|
для: demonow
(27.02.2012 в 23:35)
| | Примерно так и есть. Посмотрите еще картинку у Sfinks, тоже хорошая. Представьте, что функция вызывает не себя, а какую-то другую функцию с другим названием - она же просто дождется когда она выполниться и пойдет выполнять оставшийся код. Тут тоже самое, только экземпляров функции 10 штук. | |
|
|
|
|
|
|
|
для: cheops
(28.02.2012 в 00:19)
| | Все я понял, спасибо огромное всем, кто помог разобраться, это все дело было вызвано примером из книги, там рекурсивно дерево каталогов нужно вывести.Поэтому так важно четко знать смысл рекурсии.Кстате а на чем вы рисунки составляли? | |
|
|
|
|
|
|
|
для: demonow
(28.02.2012 в 00:25)
| | >Кстате а на чем вы рисунки составляли?
Я в Visio. | |
|
|
|