<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=299070</guid>
        <pubDate>Fri, 13 Feb 2004 22:08:53 +0000</pubDate>
        <title>Рекурсия</title>
        <link>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=299070</link>
        <description><![CDATA[KiRiK: К плюсам также можно отнести и то, что рекурсия - единственно возможный способ программирования деревьев (конечно можно извращаться - эммулировать стэк и т.д. но это мы не считаем). Про деревья см. соответствующие раздел (если он есть, в чем я пока не уверен).<br>
<br>
<span class="tag-color tag-color-named" data-value="red" style="color: red">[Нет. Есть одна тема, там где &quot;фиксные выражения&quot; в ней есть серьёзный пример с деревьями. Но без описания.]</span>]]></description>
        <author>KiRiK</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=278511</guid>
        <pubDate>Sat, 10 Jan 2004 10:32:16 +0000</pubDate>
        <title>Рекурсия</title>
        <link>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=278511</link>
        <description><![CDATA[tserega: В чем плюсы и минусы рекурсии?<br>
Главный минус - тормозА. Часто рекурсивные процедуры и функции работают ОЧЕНЬ медленно.<br>
Для примера: вычисление чисел Фиббоначчи. <br>
F(0) = F(1) = 1, F(N) = F(N - 1) + F(N - 2), N &gt;= 2<br>
Очевидное рекурсивное решение:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Function Fib(N : Byte) : Longint;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;If (N = 0) Or (N = 1) Then Fib:=1 Else</div><div class="code_line">&nbsp;Fib:=Fib(N - 1) + Fib(N - 2);</div><div class="code_line">End;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Вычисление Fib(20) занимает очень много времени, т.к. многие значения функции пересчитываются по многу раз. Построим &quot;дерево&quot; вычислений Fib(5).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Fib(5)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Fib(4) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Fib(3)</div><div class="code_line">&nbsp;&nbsp; &nbsp;Fib(2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Fib(3) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Fib(2) &nbsp; &nbsp; &nbsp;Fib(1)</div><div class="code_line">Fib(1) Fib(0) &nbsp; &nbsp; &nbsp;Fib(2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Fib(1) &nbsp; &nbsp; &nbsp; Fib(1) Fib(0)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Fib(1) Fib(0)</div></ol></div></div></div></div><br>
Можно заметить, что Fib(2) вычисляется 3 раза&#33; Для вычисления Fib(5) потребовалось 16 рекурсивных вызовов. В общем случае число вызовов Fib(N) пропорционально 2^N.<br>
Плюсы - легкое программирование рекурентных формул и алгоритмов.<br>
Рассмотрим пример: сгенерировать все подмножества данного множества.<br>
Пусть есть N предметов, каждый из которых можно взять, или не взять. Значит, число вариантов 2^N.<br>
Решение может быть таким:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Var N : Longint; {Число предметов}</div><div class="code_line">Procedure Solve(S : String; P : Longint); {S - текущий комплект, P - номер предмета,который рассматриваем}</div><div class="code_line">Begin</div><div class="code_line">&nbsp;If (P &#62; N) Then {если проверили все N предметов}</div><div class="code_line">&nbsp;&nbsp;Writeln(S) Else {выводим на экран: 0 - предмета нет, 1 - есть}</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; Solve(S + &#39;1&#39;, P + 1); {можем взять очередной предмет}</div><div class="code_line">&nbsp;&nbsp; Solve(S + &#39;0&#39;, P + 1); {а можем не взять}</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;N:=3;</div><div class="code_line">&nbsp;Solve(&#39;&#39;, 1);</div><div class="code_line">End.</div></ol></div></div></div></div>]]></description>
        <author>tserega</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=277047</guid>
        <pubDate>Wed, 07 Jan 2004 21:10:52 +0000</pubDate>
        <title>Рекурсия</title>
        <link>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=277047</link>
        <description><![CDATA[lamachok: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><strong class='tag-b'>@Hgpeu</strong>, 27.12.03, 04:24<br>
также будет процедура, вызывающая другую процедуру, которая, в свою очередь, обращается к первой процедуре (косвенная рекурсия). </div></div><br>
При этом нарушаются правила Паскаля, <br>
т.к. вышестоящая подпрограмма не знает о существовании нижестоящей. <br>
Для того, что бы всё работало тип-топ, надо использовать <strong class='tag-b'>опережающее описание</strong>. <br>
Например:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Procedure b(i:integer);Forward;</span><br>
<span class="tag-color tag-color-named" data-value="red" style="color: red">Procedure a(j:integer);<br>
begin <br>
b(i)<br>
end;</span><br>
<span class="tag-color tag-color-named" data-value="green" style="color: green">Procedure b(i:integer);<br>
begin <br>
a(j);<br>
end;</span></div></div><br>
P.S. если не нравится могу удалить :)<br>
<span class="tag-color tag-color-named" data-value="red" style="color: red">[Оставь, нравится %)]</span>]]></description>
        <author>lamachok</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=272594</guid>
        <pubDate>Mon, 29 Dec 2003 14:24:00 +0000</pubDate>
        <title>Рекурсия</title>
        <link>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=272594</link>
        <description><![CDATA[Some1: Если вы не понимаете, но хотите знать, почему важно использовать директиву {&#036;S+} (слежение за переполнением стека), то читайте тему &quot;<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=40017' target='_blank'>Как устроены переменные паскаля</a>&quot; в которой детально изложен принцип выделения памяти под переменные, объяснено, как используется стек, и для чего он нужен в процедурах или функциях (в том числе и рекурсивных)]]></description>
        <author>Some1</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=271346</guid>
        <pubDate>Sat, 27 Dec 2003 03:24:30 +0000</pubDate>
        <title>Рекурсия</title>
        <link>https://forum.sources.ru/index.php?showtopic=41657&amp;view=findpost&amp;p=271346</link>
        <description><![CDATA[@Hgpeu: <strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Рекурсия</span></strong><br>
<br>
Подпрограмма называется <em class='tag-i'>рекурсивной</em>, если она вызывает саму себя (<em class='tag-i'>прямая рекурсия</em>). Рекурсивной также будет процедура, вызывающая другую процедуру, которая, в свою очередь, обращается к первой процедуре (<em class='tag-i'>косвенная рекурсия</em>). Возможны и более сложные конструкции.<br>
<br>
При написании рекурсивных программ следует помнить, что при рекурсивном вызове процедурой самой себя или другой процедуры следует соблюдать определенные «правила предосторожности». Рекомендуется компилировать программу с директивой {&#036;S+}. Эта директива включает проверку переполнения стека (области памяти, в которой хранится состояние вызывающей подпрограммы). Если в процессе выполнения программы происходит переполнение стека, вызов процедуры или функции, откомпилированной с опцией {&#036;S+}, приводит к завершению работы программы, а на дисплей выдается сообщение об ошибке. Полезно также использовать директиву {&#036;R+}, включающую проверку диапазона переменных. В начале каждой процедуры (функции), вызываемой рекурсивно, можно разместить строку <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">if keypressed then Halt</div></ol></div></div></div></div>. В этом случае при зависании программы вместо перезагрузки будет достаточно нажать любую клавишу.<br>
<br>
Количество рекурсивных вызовов называется <em class='tag-i'>глубиной рекурсии</em>. Глубина рекурсии должна быть конечной. Позаботиться об этом должен программист, выбирающий или разрабатывающий рекурсивный алгоритм.<br>
<br>
Признаком использования рекурсии является возможность разбиения задачи на две части: простую и примитивную. Простая задача должна быть сходной по решению с общей задачей.<br>
<br>
Рассмотрим классический пример: «необходимо найти факториал числа» (факториал: y=n&#33; = 1*2*3*4*…*n)<br>
1&#33;=1<br>
2&#33;=1*2=1&#33;*2<br>
3&#33;=1*2*3=2&#33;*3<br>
n&#33;=(n-1)&#33;*n<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function f(n: longint): longint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if n=1 then f:=1</div><div class="code_line">&nbsp;&nbsp;else f:=f(n-1)*n;</div><div class="code_line">end;</div></ol></div></div></div></div>]]></description>
        <author>@Hgpeu</author>
        <category>Pascal: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	