【问题标题】:removing piped dot in string common lisp删除字符串 common lisp 中的管道点
【发布时间】:2013-12-09 12:02:28
【问题描述】:

我的任务是解析那个列表

(100 30 5 . 50 6)

到 135.56 号

输入列表的格式始终相同

我写过:

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

并输出 Ive "135|.|56" 然后 read-from-string 不会读取它,所以...

你知道我怎么做这个解析吗?

使用或不使用上面的代码

【问题讨论】:

  • 你怎么称呼这个? CCL 不允许我有这样的列表。
  • 查看my answerLisp 中的递归范围添加句点? 了解更多关于点在列表中的含义。如果您想要一个名称为字符串"." 的符号,则需要将其写为|.|\.
  • 不是关于你的特定问题,而是关于你的一般解决方案:如果你应该产生一个像102.309 这样的数字,输入(100 00 2 . 300 00 9),这不会中断,因为你会最终产生12.39?

标签: parsing common-lisp clisp


【解决方案1】:

您的方法看起来并不特别稳健。也很难理解输入列表是什么。点是符号吗,比如|.|?垂直条正在转义名称,因此它不会与 Lisp 中点字符的内置用法发生冲突。它以点对形式使用,代表 cons 单元格:(a . b)

如果它是一个符号,那么您可以编写符号而不转义为字符串。一、转义:

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

接下来,没有:

CL-USER 6 > (princ-to-string '|.|)
"."

【讨论】:

    【解决方案2】:

    您的列表 (100 30 5 . 50 6) 在 Common Lisp 中不是有效的列表结构。 “点对”必须在点之后只有一个元素。如果您想了解更多信息,请查看您最喜欢的 Common Lisp Book 如何从 cons 单元构建列表。 (例如Peter Seibels "Practical Common Lisp"

    所以你不能把这个字符串解析为一个列表——你需要一个预处理步骤。

    (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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多