Common Lisp:删除具有相同cdr的元素

 只想活得快乐的魔羯 发布于 2022-12-06 11:00
  • php
  • (分配帮助,对我很轻松)(我必须在不使用破坏性功能(setf)的情况下这样做)

    使用常见的lisp,作为一些代码的一部分,我需要能够:

    获取列表列表,比较2个元素的cdr,如果相等则忽略第一个元素,如果不相等则尝试将第一个元素与列表中的下一个未检查元素进行比较.

    一些例子澄清:

    ((1 1 1)(2 1 1)(3 1 1)) - >((3 1 1))

    ((2 2 0)(4 1 1)(1 2 0)(3 0 1)(8 1 1)) - >((1 2 0)(3 0 1)(8 1 1))

    (defun simplify2 (vari)
        ;If last term: stop
        (if (equal (cdr vari) nil) vari
    
            ;If cdr of first and second term are equal...
            (if (equal (cdar vari) (cdr (cadr vari)))
    
                ;Ignore the first term and continue with the rest of the list
                (simplify2 (cdr vari))
    
                ;Otherwise (this is the line which isn't working)
                (cons (car vari) (simplify2 (cdr vari))))))
    

    目前,当所有"喜欢"术语在列表中彼此相邻放置时,代码才能正常工作.

    1 个回答
    • Le Petit Prince在评论中建议使用remove-duplicatelicates可能就是你想要的. remove-duplicates是非破坏性的(参见delete-duplicatelicates,它可能是破坏性的),并且它被指定为返回一个新列表,其中除了元素的最后一个实例之外的所有元素都被省略(强调添加):

      删除,重复

      remove-duplicates返回一个已修改的序列副本,从该序列中删除了与序列中出现的另一个元素匹配的任何元素....序列的元素进行比较成对,并且如果任何两个匹配,则在前面的序列中出现的一个被丢弃,除非从端是真实的,在这种情况下,一个在后面的序列被丢弃.

      您需要指定一个参数,以指示实际应该比较的是元素的cdr,以及一个测试参数,以指示它们应该与相等进行比较.从而:

      (remove-duplicates '((1 1 1) (2 1 1) (3 1 1))
                         :test 'equal 
                         :key 'cdr)
      ;=> ((3 1 1))
      

      (remove-duplicates '((2 2 0) (4 1 1) (1 2 0) (3 0 1) (8 1 1))
                         :test 'equal
                         :key 'cdr)
      ;=> ((1 2 0) (3 0 1) (8 1 1))
      

      2022-12-11 02:56 回答
    撰写答案
    今天,你开发时遇到什么问题呢?
    立即提问
    热门标签
    PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有