удаление точки в строке common lisp

моя задача разобрать этот список

(100 30 5 . 50 6)

к номеру 135.56

формат входного списка всегда одинаков

и я написал:

(reduce 
    'string-concat 
    (mapcar 
        (lambda (x) (remove #\0 x)) 
        (mapcar 
            'write-to-string
            l
        )
    )
)

и вывод у меня "135|.|56", а затем чтение из строки не читает его, так что...

У вас есть идеи, как я могу сделать этот разбор?

используя или не код выше


person Morgaroth    schedule 09.12.2013    source источник
comment
Как вы это называете? CCL не позволяет мне иметь такой список.   -  person uselpa    schedule 09.12.2013
comment
Взгляните на мой ответ на Рекурсивный диапазон в Lisp добавляет точку?, чтобы узнать больше о том, что точка означает в списке. Если вы хотите иметь символ, имя которого представляет собой строку ".", вам нужно будет записать его как |.| или \..   -  person Joshua Taylor    schedule 09.12.2013
comment
Не о вашей конкретной проблеме, а о вашем общем решении: не сломается ли это, если вы должны создать число, подобное 102.309, которое будет входным (100 00 2 . 300 00 9), поскольку в конечном итоге вы получите 12.39?   -  person Joshua Taylor    schedule 09.12.2013


Ответы (2)


Ваш подход не выглядит особенно надежным. Также трудно понять, что такое входной список. Является ли точка символом, как в |.|? Вертикальные черты скрываются от имени, чтобы оно не конфликтовало со встроенным использованием символа точки в Лиспе. Он используется в точечных парах, обозначающих минус-ячейки: (a . b).

Если это символ, то вы можете написать символ, не переходя в строку. Во-первых, с побегом:

CL-USER 5 > (write-to-string '|.|)
"\\."

Далее без:

CL-USER 6 > (princ-to-string '|.|)
"."
person Rainer Joswig    schedule 09.12.2013

Ваш список (100 30 5 . 50 6) не является допустимой структурой списка в Common Lisp. Пара с точками должна иметь только один элемент после точки. Если вы хотите узнать об этом больше, посмотрите в своей любимой книге Common Lisp, как строятся списки из cons-ячеек. (Например, Peter Seibels "Practical Общий Лисп")

Таким образом, вы не можете разобрать эту строку как список как таковой — вам нужен шаг предварительной обработки.

(defun pre-processing (str)
  (let ((idx (position #\. str)))
    (list (read-from-string (concatenate 'string (subseq str 0 idx) ")"))
          (read-from-string (concatenate 'string "(" (subseq str (1+ idx)))))))

Эта функция разбивает вашу строку на два списка, которые вы можете обрабатывать так, как хотите.

CL-USER 1 > (pre-processing "(100 30 5 . 50 6)")
((100 30 5) (50 6))
person Frank Zalkow    schedule 09.12.2013