Рекурсия
Рекурсия
Отсутствие в XSLT изменяемых переменных (оценим красоту этой тавтологии) как, впрочем, и многое другое, делает этот язык совершенно непохожим на многие классические языки программирования. В этом разделе мы опишем рекурсию [Кормен и др. 2000, Кнут 2000] — чрезвычайно простую, но в то же время исключительно мощную технику, которая в большинстве случаев компенсирует нехватку в XSLT переменных и других процедурных конструкций.
Не вдаваясь в строгие определения дискретной математики, можно сказать, что рекурсия это всего лишь описание объекта или вычисления в терминах самого себя. Пожалуй, самым простым примером рекурсии является факториал, функция, которая математически определяется как:
0!=1
n!=n?(n-1)!
Программа на процедурном языке (например, таком, как Java), вычисляющая факториал совершенно тривиальна:
int factorial(int n) {
if (n == 0) return 1;
else return n * factorial(n-1);
}
Попробуем запрограммировать факториал на XSLT. Мы уже научились создавать собственные функции (вернее, конструкции, похожие на них) с помощью одних только именованных шаблонов, значит написать функцию, которая бы вызывала сама себя, будет не так уж и сложно.
Листинг 11.9. Именованный шаблон, вычисляющий факториал
<xsl:template name="factorial">
<xsl:param name="n"/>
<xsl:choose>
<xsl:when test="$n=0">1</xsl:when>
<xsl:otherwise>
<xsl:variable name="n-1">
<xsl:call-template name="factorial">
<xsl:with-param name="n" select="$n-1"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$n * number($n-1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Вызвав этот шаблон с параметром n равным 6 следующим образом:
<xsl:call-template name="factorial">
<xsl:with-param name="n" select="number(6)"/>
</xsl:call-template>
мы получим текстовый узел, значение которого будет равно "720".
Очевидным требованием к рекурсивным функциям является возможность выхода из рекурсии. Если бы в определении факториала не было указано, что 0!=1, вычисления так бы и продолжались без конца.
Главным минусом рекурсии является требовательность к ресурсам. Каждый раз, при вызове именованного шаблона, процессор должен будет каким-то образом сохранять в памяти передаваемые ему формальные параметры. Например, если мы попробуем сосчитать факториал от 170, процессору понадобится держать в памяти сразу 170 чисел. Безусловно, в случае с факториалом это не является большой проблемой — точность 64-битных чисел исчерпается гораздо раньше, чем закончится память, но в случае хранения в переменных действительно больших объемов информации (например, частей деревьев) такая угроза существует. Кроме того, рекурсивные решения, как правило, работают медленнее, чем решения, не использующие рекурсию.
Так в чем же смысл использования рекурсии? Дело в том, что вследствие определенных ограничений (связанных, в частности с неизменяемыми переменными) в XSLT существуют задачи, которые не могут быть реализованы иначе кроме как через рекурсию. Самым характерным примером такой задачи являются циклы.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
3.13.7. Рекурсия в регулярных выражениях
3.13.7. Рекурсия в регулярных выражениях Возможность повторно обращаться к подвыражению позволяет создавать рекурсивные регулярные выражения. Например, данный код находит любое вложенное выражение с правильно расставленными скобками (спасибо Эндрю Джексону):str = "а *
9.2.3. Стек и рекурсия
9.2.3. Стек и рекурсия В качестве примера изоморфизма, существующего между стеком и рекурсией, рассмотрим классическую задачу о Ханойской башне.По легенде где-то далеко на востоке существует старинный храм. Обитающие в нем монахи заняты решением единственной задачи:
7.5. Рекурсия
7.5. Рекурсия Функция, которая прямо или косвенно вызывает сама себя, называется рекурсивной. Например:int rgcd( int vl, int v2 ){if ( v2 != 0 )return rgcd( v2, vl%v2 );return vl;}Такая функция обязательно должна определять условие окончания, в противном случае рекурсия будет продолжаться бесконечно.
33.4. Рекурсия
33.4. Рекурсия Может ли сценарий рекурсивно вызывать себя самого? Да,
Рекурсия
Рекурсия Отсутствие в XSLT изменяемых переменных (оценим красоту этой тавтологии) как, впрочем, и многое другое, делает этот язык совершенно непохожим на многие классические языки программирования. В этом разделе мы опишем рекурсию [Кормен и др. 2000, Кнут 2000] — чрезвычайно
Лекция 12. Рекурсия
Лекция 12. Рекурсия Рекурсия. Стек. Создание собственного стека. Применение рекурсии. "Чтобы понять рекурсию, сначала необходимо понять рекурсию".Данное высказывание очень четко выражает суть рекурсии. Рекурсия является базовой концепцией программирования вообще, а не
Рекурсия
Рекурсия И еще один важный вопрос, связанный с вызовом функций.Мы уже узнали, что функции могут вызывать другие функции, конечно, если те уже определены. Но функции могут также вызывать и сами себя. Такой прием программирования называется рекурсией и иногда бывает очень