Составители:
Рубрика:
Пример 1.4. Функция Reverse, обращающая список.
Например, Reverse( y ) = ( d c b a ) для y = ( a b c d ).
Reverse( y ) = if Null( y ) then Nil
else Concat ( Reverse( Tail( y) ), Cons( Head( y ), Nil ) ).
Для лучшего понимания работы функции Reverse рассмотрим последова-
тельность вызовов функций и возвращаемых ими значений при обращении
списка из двух элементов y = ( a b ) (рис.1.18).
Вызовы Возвращаемые значения
Reverse( (a b) )
Concat( Reverse(( b )),Cons( a, Nil ))
* Reverse( (b) )
Concat(Reverse( Nil ),Cons( b, Nil ))
* Reverse( Nil )
* Cons( b,Nil )
* Cons( a,Nil )
Cons( b, Concat( Nil, (a) ) )
* Concat( Nil, (a) )
( b a )
( b a )
( b )
( b )
Nil
( b )
( a )
( b a )
( a )
Рис. 1.18. Последовательность вызовов функций при обращении списка из двух элементов
Вызов функции, с которого начинается вычисление значения фактического
параметра ранее вызванной функции, на рисунке помечен символом *. Воз-
вращаемые значения, формируемые в процессе вычислений позднее по вре-
мени, сдвинуты вправо относительно ранее сформированных значений. На
рисунке для краткости не отражены вызовы селекторов Head и Tail. Вместо
этого на соответствующие места подставлены возвращаемые ими значения.
Заметим, что количество вызовов конструктора Cons при обращении спи-
ска из n элементов равно n + ( n
−
1 ) + .. + 1 = n ( n + 1 ) / 2 и может быть дос-
таточно велико при большом n. Это важно, поскольку, как станет ясно из
дальнейшего изложения, именно количество вызовов конструктора Cons в
значительной степени определяет объем потребляемых вычислительных ре-
сурсов. В следующем примере рассмотрено другое определение функции об-
ращения списка, позволяющее сократить объем вычислений.
Пример 1.5.
Функция Reverse1, обращающая список. С целью уменьшения
количества вызовов конструктора Cons введена вспомогательная функция Rev,
второй параметр которой используется как "накапливающий".
Rev( y, z ) = if Null( y ) then z
else Rev ( Tail( y ), Cons ( Head( y ), z ) );
Reverse1 ( y ) = Rev ( y, Nil ).
Последовательность вызовов функций и возвращаемых ими значений при
обращении списка из двух элементов y = ( a b ), порождаемая вызовом функ-
ции Reverse1, приведена на рис. 1.19.
21
Пример 1.4. Функция Reverse, обращающая список. Например, Reverse( y ) = ( d c b a ) для y = ( a b c d ). Reverse( y ) = if Null( y ) then Nil else Concat ( Reverse( Tail( y) ), Cons( Head( y ), Nil ) ). Для лучшего понимания работы функции Reverse рассмотрим последова- тельность вызовов функций и возвращаемых ими значений при обращении списка из двух элементов y = ( a b ) (рис.1.18). Вызовы Возвращаемые значения Reverse( (a b) ) (ba) Concat( Reverse(( b )),Cons( a, Nil )) (ba) * Reverse( (b) ) (b) Concat(Reverse( Nil ),Cons( b, Nil )) (b) * Reverse( Nil ) Nil * Cons( b,Nil ) (b) * Cons( a,Nil ) (a) Cons( b, Concat( Nil, (a) ) ) (ba) * Concat( Nil, (a) ) (a) Рис. 1.18. Последовательность вызовов функций при обращении списка из двух элементов Вызов функции, с которого начинается вычисление значения фактического параметра ранее вызванной функции, на рисунке помечен символом *. Воз- вращаемые значения, формируемые в процессе вычислений позднее по вре- мени, сдвинуты вправо относительно ранее сформированных значений. На рисунке для краткости не отражены вызовы селекторов Head и Tail. Вместо этого на соответствующие места подставлены возвращаемые ими значения. Заметим, что количество вызовов конструктора Cons при обращении спи- ска из n элементов равно n + ( n − 1 ) + .. + 1 = n ( n + 1 ) / 2 и может быть дос- таточно велико при большом n. Это важно, поскольку, как станет ясно из дальнейшего изложения, именно количество вызовов конструктора Cons в значительной степени определяет объем потребляемых вычислительных ре- сурсов. В следующем примере рассмотрено другое определение функции об- ращения списка, позволяющее сократить объем вычислений. Пример 1.5. Функция Reverse1, обращающая список. С целью уменьшения количества вызовов конструктора Cons введена вспомогательная функция Rev, второй параметр которой используется как "накапливающий". Rev( y, z ) = if Null( y ) then z else Rev ( Tail( y ), Cons ( Head( y ), z ) ); Reverse1 ( y ) = Rev ( y, Nil ). Последовательность вызовов функций и возвращаемых ими значений при обращении списка из двух элементов y = ( a b ), порождаемая вызовом функ- ции Reverse1, приведена на рис. 1.19. 21
Страницы
- « первая
- ‹ предыдущая
- …
- 19
- 20
- 21
- 22
- 23
- …
- следующая ›
- последняя »