На этом шаге мы рассмотрим примеры работы со строками .
Вначале заметим, что строкой для нас является P-имя строкового атома. Это очень важное замечание!
Однако в версии muLISP81 отсутствуют функции, позволяющие оперировать с P-именами строковых атомов. Тем не менее, используя функции PACK и UNPACK можно свести работу с P-именами к операциям со списками.
Функция
(UNPACK А)
"разбивает" имя атома А на список атомов, имена которых составлены из символов имени атома А. Например:
$ (UNPACK ABC) (A B C)
Функция
(PACK Список)
выполняет операцию, обратную операции, выполняемой функцией UNPACK. Например:
$ (PACK (A B C)) ABC
(DEFUN ATOMCAR (LAMBDA (X) ; Функция возвращает первый символ имени атома X ; (CAR (UNPACK X)) )) ; ---------------------- ; (DEFUN ATOMCDR (LAMBDA (X) ; Функция возвращает имя атома X без его первого символа ; (PACK (CDR (UNPACK X))) ))
(DEFUN NUM-STRING (LAMBDA (X)
; Перевод целого неотрицательного числа в литеральный атом ;
(PACK (UNPACK X))
))
(DEFUN STRING-NUM (LAMBDA (X) ; Перевод списка цифр в список, содержащий соответствующие ; ; однозначные числа ; (COND ( (NULL X) NIL ) ( T (CONS (POSITION (CAR X) (UNPACK 123456789)) (STRING-NUM (CDR X)) ) ) ) )) ; ---------------------------- ; (DEFUN POSITION (LAMBDA (X LST) ; Функция POSITION возвращает положение атома X в ; ; одноуровневом списке LST (первый элемент имеет ; ; номер 1). Если элемента в списке нет, то функция ; ; возвращает 0 ; (COND ( (NULL LST) 0 ) ( (EQ X (CAR LST)) 1 ) ( (MEMBER X LST) (+ 1 (POSITION X (CDR LST))) ) ( T 0 ) ) ))
(DEFUN LONGMULT (LAMBDA (X Y) ; "Длинное" умножение вещественных чисел: ; ; X и Y - атомы, представляющие вещественные числа. ; ; Например, числу 567.098 соответствует представление ; ; A567#098, где A - любая буква, символ # указывает ; ; положение десятичной точки в числе. ; ; Результат возвращается в таком же виде! ; (PACK (REVERSE (INSERT # (+ (+ (- (LENGTH (CDR (UNPACK X))) (POSITION # (CDR (UNPACK X)))) (- (LENGTH (CDR (UNPACK Y))) (POSITION # (CDR (UNPACK Y)))) ) 1 ) (REVERSE (UNPACK (* (NUMBER (STRING-NUM (DELETE (POSITION # (CDR (UNPACK X))) (CDR (UNPACK X))))) (NUMBER (STRING-NUM (DELETE (POSITION # (CDR (UNPACK Y))) (CDR (UNPACK Y))))) ) ) ) ) ) ) )) ; ------------------------- ; (DEFUN NUM-STRING (LAMBDA (X) ; Перевод целого неотрицательного числа ; ; в литеральный атом ; (PACK (UNPACK X)) )) ; ------------------------- ; (DEFUN STRING-NUM (LAMBDA (X) ; Перевод списка цифр в список, содержащий ; ; соответствующие однозначные числа ; (COND ( (NULL X) NIL ) ( T (CONS (POSITION (CAR X) (UNPACK 123456789)) (STRING-NUM (CDR X)) ) ) ) )) ; ----------------------- ; (DEFUN NUMBER (LAMBDA (LST) ; Дан числовой список LST, содержащий однозначные ; ; числа. "Построить" целое число из элементов дан- ; ; ного списка ; (COND ( (NULL LST) 0 ) ( T (+ (* (CAR LST) (STEPEN 10 (- (LENGTH LST) 1)) ) (NUMBER (CDR LST)) ) ) ) )) ; ----------------------- ; (DEFUN STEPEN (LAMBDA (X A) ; Возведение целого числа X в целую неотрицательную ; ; степень A ; (COND ( (ZEROP A) 1 ) ( (ZEROP (- A 1)) X ) ( T (* (STEPEN X (- A 1)) X) ) ) )) ; --------------------------- ; (DEFUN INSERT (LAMBDA (X N LST) ; Функция вставляет элемент X на N-ю позицию ; ; в список LST ; (COND ( (NULL LST) (CONS X LST) ) ( (EQ N 1) (CONS X LST) ) ( T (CONS (CAR LST) (INSERT X (- N 1) (CDR LST))) ) ) )) ; ------------------------- ; (DEFUN DELETE (LAMBDA (N LST) ; Функция удаляет N-й элемент из списка LST ; (COND ( (EQ N 1) (CDR LST) ) ( T (CONS (CAR LST) (DELETE (- N 1) (CDR LST))) ) ) )) ; ---------------------------- ; (DEFUN POSITION (LAMBDA (X LST) ; Функция POSITION возвращает положение атома X в ; ; одноуровневом списке LST (первый элемент имеет ; ; номер 1). Если элемента в списке нет, то функция ; ; возвращает 0 ; (COND ( (NULL LST) 0 ) ( (EQ X (CAR LST)) 1 ) ( (MEMBER X LST) (+ 1 (POSITION X (CDR LST))) ) ( T 0 ) ) ))
На следующем шаге мы рассмотрим работу со строками в muLISP85.