[room] Вопрос по Lisp

Alexey Voinov =?iso-8859-1?q?voins_=CE=C1_voins=2Eprogram=2Eru?=
Вс Янв 28 11:33:39 MSK 2007


Денис Смирнов <mithraen на altlinux.ru> writes:

> On Sat, Jan 27, 2007 at 02:28:26PM +0300, Alexey Voinov wrote:
>
> AV> Не, ты не понимаешь. :) Тупо - это вот так  (используем srfi-1):
> AV> (define (trim-zeroes-right data)
> AV>   (reverse (drop-while zero? (reverse data)))
>
> Гм. Логично. В описании к тому же nyquist я почему-то drop-while не нашел
> :-/
Это из http://srfi.schemers.org/srfi-1/srfi-1.html
В Сommon Lisp наверняка аналогичная функция есть в стандартной
библиотеке. :)

>  AV> (define (trim-zeroes-right data)
>  AV>   (let loop ((newlen (vector-length data)))
>  AV>     (let ((index (- newlen 1)))
>  AV>       (cond ((zero? newlen)
>  AV>              '#())
>  AV>             ((zero? (vector-ref data index))
>  AV>              (loop index))
>  AV>             (else
>  AV>              (vector-copy data 0 newlen))))))
>
> Только эту конструкцию я не смог прочитать:
>
> AV>       (cond ((zero? newlen)
> AV>              '#())
> AV>             ((zero? (vector-ref data index))
> AV>              (loop index))
Если мы в подсчёте нулей дошли до начала вектора (длина нового вектора
равна 0), то возвращаем сразу пустой вектор, не дёргая копирования и
выйдем из цикла.
Если элемент в текущей позиции (index всегда на единицу меньше newlen)
равен 0, то повторить процедуру сначала, уменьшив длину нового вектора
на единицу (т.е. взять вместо длины - индекс). (let <name> ...) -
очень удобная и полезная конструкция в scheme. :) На CL наверняка этот
цикл будет проще записать каким-нибудь другим способом.
Если мы нашли первый не-нуль от конца, то скопируем все нужные
элементы и выйдем из цикла.

-- 
Voins


Подробная информация о списке рассылки smoke-room