【问题标题】:How to get rid of duplicates in a list, but keep the order如何摆脱列表中的重复项,但保持顺序
【发布时间】:2011-12-30 01:50:24
【问题描述】:

我在 DrRacket 中使用 Intermediate Student with Lambda,我想知道如何删除列表中的重复项,同时保持顺序。例如(remove-dup (list 2 5 4 5 1 2)) 将产生(list 2 5 4 1)。到目前为止,我有这个:

(define (remove-duplicates lst)
  (cond
    [(empty? lst) empty]
    [(member? (first lst) (rest lst)) 
     (remove-duplicates (rest lst))]
    [else (cons (first lst) (remove-duplicates (rest lst)))]))

,但是有一个问题,因为它没有保持顺序。有人可以指出我正确的方向吗?谢谢你的时间。

【问题讨论】:

  • 实际上,它看起来确实保留了顺序,只是没有保留第一个重复元素。您确定您的解决方案不正确吗?
  • 很遗憾,解决方案不正确。例如,如果我有删除重复项 (1 2 5 1 4),我想要 (list 1 2 5 4),而不是 (list 2 5 1 4) 的实际值。抱歉举了一个不好的例子。
  • 我正在考虑在列表的第一个上做类似 cons 的事情,然后在列表的其余部分上使用过滤器和第一个数字。除了,我不知道如何实现哈哈。
  • 如果你了解了累加器,我会考虑在这里使用它们(假设这是一个类)。
  • 这个问题不需要累加器;你可以用一个辅助函数来做到这一点。我会考虑将其称为“删除”。渐近复杂度是一样的。

标签: scheme racket


【解决方案1】:

如果您的目标是让功能正常运行,而不是一些家庭作业问题,那么您无需做任何事情,只需使用remove-duplicates

Welcome to Racket v5.2.
-> (remove-duplicates (list 2 5 4 5 1 2))
'(2 5 4 1)

【讨论】:

  • 我有球拍 6.0.1 但它告诉我该功能未定义
  • 您需要使用常规语言,而不是学生语言。
【解决方案2】:

这是解决方案:

(define (remove-duplicates lon)
  (foldr (lambda (x y) (cons x (filter (lambda (z) (not (= x z))) y))) empty lon))

【讨论】:

    【解决方案3】:

    老问题,但这是 J-Y 想法的实现。

    (define (dup-rem lst)
      (cond
        [(empty? lst) empty]
        [else (cons (first lst) (dup-rem (filter (lambda (x) (not (equal? (first lst) x))) lst)))]))
    

    【讨论】:

      【解决方案4】:

      SRFI-1 有delete-duplicates,尽管它效率低下。 (我对 Racket 不太熟悉,但肯定有 SRFI-1,而且来源...)

      http://srfi.schemers.org/srfi-1/srfi-1.html#delete-duplicates

      【讨论】:

      • 我查看了网站,但我认为提供的源代码在 Racket 中不起作用。
      • 您可以在 Racket 中使用srfi/1,只需将(require srfi/1) 添加到您的程序中即可。但是,第一个答案中提到的remove-duplicates 更容易获得——默认情况下它在 Racket 中。
      【解决方案5】:

      依次遍历列表,将每个元素插入哈希表或其他字典中。如果您尝试插入一个已经在哈希表中的元素,请不要将其添加到传出列表中。

      【讨论】:

        【解决方案6】:

        您需要做的是在整个时间内以相反的顺序进行比较。您可以使用reverse 函数以相反的顺序返回列表。这样,您总是删除元素的第 2 次以上出现,而不是第一次出现。这是一个示例,但它使用的是 letif 而不是 cond 表达式。

        http://www.cs.bgu.ac.il/~elhadad/scheme/duplicates.html

        祝你作业顺利:)

        【讨论】:

          【解决方案7】:

          嗯,我最近刚参加了一场球拍考试,:/

          “标准”remove-duplicates 工作正常,但我在 drRacket 中使用相当大,因此必须使用 (require racket/list) 加载它

          这是另一种方式:)

          使用突变(不是真正的球拍精神,但......它有效。)

              (define (set l)
                  (define the-set '())
                      (begin (for-each
                                 (lambda (x)
                                      (if (member x the-set)
                                          #t
                                      (set! the-set (cons x the-set))))
                                 l)
                             (reverse the-set)))
          

          希望这会有所帮助...干杯!

          【讨论】:

            【解决方案8】:

            我不确定这是否是作业,但如果是的话,我会发布这个想法。如果没有告诉我,我可以在这里提出解决方案。

            您需要跟踪您找到的独特物品,您可以使用辅助列表(如累加器)来跟踪您目前找到的物品。

            每当您查看另一个项目时,请检查它是否在辅助列表中。如果没有添加到辅助列表中。

            您最终会得到与您要查找的内容相反的顺序,因此您只需(反转...)它就会得到答案。

            【讨论】:

            • 您最好将哈希集设置为列表以保留您看到的项目。使用列表,函数是 Theta (n^2) 。使用哈希集,它是@​​987654322@。
            猜你喜欢
            • 1970-01-01
            • 2021-12-23
            • 2010-10-03
            • 1970-01-01
            • 1970-01-01
            • 2011-03-05
            • 2012-06-19
            • 1970-01-01
            相关资源
            最近更新 更多