Составители:
Рубрика:
Определенная в примере 1.2 функция Concat, примененная, например, к
спискам y = ( a (b ш) ), z = ( d e ) должна возвратить значение Concat ( y, z ) =
= ( a ( b c ) d e ) . На Паскале она может быть записана следующим образом:
function Concat ( y, z : H_list ) : H_list;
begin
if Null ( y ) then Concat := Copy ( z )
else Concat := Cons( Copy( Head( y ) ), Concat( Tail( y ), z ) );
end;
Функция создает новый иерархический список из копий атомов, входящих
в соединяемые списки. На рис.1.23 изображена последовательность вызовов
функций и возвращаемых ими значений, порождаемая вызовом функции
Concat. Верхние индексы на рисунке использованы для обозначения номе-
ров экземпляров (копий) атомов. Для краткости все вызовы функций Head,
Tail, а также большинство вызовов Copy, заменены на возвращаемые этими
функциями значения.
Вызовы Возвращаемые значения
C
onca
t
( ( a ( b c ) ), ( d e ) )
Cons( a¹, Concat( ( ( b c ) ), ( d e ) ) *Concat(
( ( b c ) ), ( d e ) )
Cons( ( b¹ c¹ ),Concat( Nil,( d e ) ) )
*Concat( Nil, ( d e ) )
Copy( ( d e ) )
( a¹ ( b¹ c¹ ) d¹ e¹ )
( a ¹ ( b¹ c¹ ) d¹ e¹ )
( ( b¹ c¹ ) d¹ e¹ )
( ( b¹ c¹ ) d¹ e¹ )
( d¹ e¹ )
( d¹ e¹ )
Рис. 1.23. Последовательность вызовов функций при соединении двух списков
Обращающая список функция Reverse, определение которой дано в примере
1.4, также может быть применена к иерархическим спискам. Например, Re-
verse( y ) = ( d ( b с ) a ) для y = ( a ( b c ) d ). На Паскале функция может иметь вид
function Reverse ( y : H_list ) : H_list;
var p1, p2 : H_list;
begin
if Null( y ) then Reverse := nil
else begin p1 := Reverse ( Tail( y ) );
p2 := Cons ( Copy ( Head( y ) ), nil );
Reverse := Concat ( p1, p2 );
Destroy( p1 ); Destroy ( p2 );
end;
end;
Как можно видеть на рис. 1.24, в процессе выполнения Reverse создаются
рабочие копии атомов, входящие во временно существующие списки. Так,
атом d копируется четыре раза, причем все копии, кроме четвертой копии d
4
,
входящей в результирующий список, уничтожаются вместе с временно суще-
ствующими списками. На рис. 1.24 уничтожаемые при выполнении процеду-
ры Destroy списки изображены в квадратных скобках.
29
Определенная в примере 1.2 функция Concat, примененная, например, к спискам y = ( a (b ш) ), z = ( d e ) должна возвратить значение Concat ( y, z ) = = ( a ( b c ) d e ) . На Паскале она может быть записана следующим образом: function Concat ( y, z : H_list ) : H_list; begin if Null ( y ) then Concat := Copy ( z ) else Concat := Cons( Copy( Head( y ) ), Concat( Tail( y ), z ) ); end; Функция создает новый иерархический список из копий атомов, входящих в соединяемые списки. На рис.1.23 изображена последовательность вызовов функций и возвращаемых ими значений, порождаемая вызовом функции Concat. Верхние индексы на рисунке использованы для обозначения номе- ров экземпляров (копий) атомов. Для краткости все вызовы функций Head, Tail, а также большинство вызовов Copy, заменены на возвращаемые этими функциями значения. Вызовы Возвращаемые значения Concat( ( a ( b c ) ), ( d e ) ) ( a¹ ( b¹ c¹ ) d¹ e¹ ) Cons( a¹, Concat( ( ( b c ) ), ( d e ) ) *Concat( ( a ¹ ( b¹ c¹ ) d¹ e¹ ) ( ( b c ) ), ( d e ) ) ( ( b¹ c¹ ) d¹ e¹ ) Cons( ( b¹ c¹ ),Concat( Nil,( d e ) ) ) ( ( b¹ c¹ ) d¹ e¹ ) *Concat( Nil, ( d e ) ) ( d¹ e¹ ) Copy( ( d e ) ) ( d¹ e¹ ) Рис. 1.23. Последовательность вызовов функций при соединении двух списков Обращающая список функция Reverse, определение которой дано в примере 1.4, также может быть применена к иерархическим спискам. Например, Re- verse( y ) = ( d ( b с ) a ) для y = ( a ( b c ) d ). На Паскале функция может иметь вид function Reverse ( y : H_list ) : H_list; var p1, p2 : H_list; begin if Null( y ) then Reverse := nil else begin p1 := Reverse ( Tail( y ) ); p2 := Cons ( Copy ( Head( y ) ), nil ); Reverse := Concat ( p1, p2 ); Destroy( p1 ); Destroy ( p2 ); end; end; Как можно видеть на рис. 1.24, в процессе выполнения Reverse создаются рабочие копии атомов, входящие во временно существующие списки. Так, атом d копируется четыре раза, причем все копии, кроме четвертой копии d4, входящей в результирующий список, уничтожаются вместе с временно суще- ствующими списками. На рис. 1.24 уничтожаемые при выполнении процеду- ры Destroy списки изображены в квадратных скобках. 29
Страницы
- « первая
- ‹ предыдущая
- …
- 27
- 28
- 29
- 30
- 31
- …
- следующая ›
- последняя »