【问题标题】:Most idiomatic way of replacing a list subsection in Lisp在 Lisp 中替换列表小节的最惯用方式
【发布时间】:2011-10-05 09:35:52
【问题描述】:

替换列表的特定子序列的最佳方法是什么? 假设我想用i 替换子序列(m e)

(sub-substitute 'i '(m e) '(y o u a n d m e))
⇒ (Y O U A N D I)

注意事项:这与函数substitute非常相似:

(substitute 'u 'i '(i are hungry))
⇒ (U ARE HUNGRY)

【问题讨论】:

    标签: list lisp common-lisp replace


    【解决方案1】:

    我不确定这是否是家庭作业,并且这是一个合理的实际问题,所以如果你刚刚被介绍给简单的列表,我会给你一个你的老师不会期望并且会好奇的简单解决方案加工。它适用于序列(向量、列表、字符串),并使用了一些 CL 的序列函数:

    (defun substitute-subsequence (new old sequence &key (test #'eql))
      (let ((position (search old sequence :test test)))
        (if position
            (concatenate (etypecase sequence
                           (string 'string)
                           (vector 'vector)
                           (list 'list))
                         (subseq sequence 0 position)
                         new
                         (subseq sequence (+ position (length old))))
            sequence)))
    

    然后:

    CL-USER> (substitute-subsequence '(i) '(m e) '(y o u a n d m e))
    (Y O U A N D I)
    CL-USER> (substitute-subsequence #(i) #(m e) #(y o u a n d m e))
    #(Y O U A N D I)
    CL-USER> (substitute-subsequence "I" "me" "you and me")
    "you and I"
    CL-USER> (substitute-subsequence "me" "I" "you and I")
    "you and me"
    

    如果这是一个家庭作业问题,您应该考虑编写特定版本的方法,该版本仅适用于您已经介绍过的列表函数。另外,请注意,在列表上连接和计算长度不是很有效,应该避免在紧密循环中使用它。您也可以尝试实现一个替代所有出现的版本。

    编辑:较短的版本,替换所有出现,但仅适用于列表:

    (defun substitute-sublists (new old list)
      (do ((pos (search old list) (search old list :start2 pos)))
          ((not pos) list)
        (setq list (append (subseq list 0 pos) new (subseq list (+ pos (length old)))))))
    

    【讨论】:

    • 不是为了作业,而是为了实现 GEB 的 MIU-system 的规则 III(即“如果 III 出现在您集合中的一个字符串中,您可以使用 @987654326 创建一个新字符串@ 代替 III”) — 我曾希望有一个优雅的解决方案来解决这个问题。
    • 您想要的功能不在标准 AFAIK 中,因此有两种可能性:要么使用提供它的库,要么您自己编写。如果您自己编写,我看不出我的代码有任何不雅之处。现在,如果您想要更短的适用于所有情况的内容:我已经更新了帖子。如果优雅意味着内置,我无能为力。
    • 抱歉,我并不是有意贬低您的代码。由于 Lisp 具有这样的列表操作能力,我希望它具有一些不需要处理位置值的标准功能。我会支持你的答案,但如果有人想到内置函数,请等待接受
    • @Baldur,无需道歉——我只是想指出我不知道“更优雅”的方式,我发布的代码应该没问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2021-12-30
    • 1970-01-01
    • 2010-09-15
    • 2019-11-07
    • 1970-01-01
    • 2013-05-01
    相关资源
    最近更新 更多