[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