【问题标题】:Scheme function that checks a list for duplicates用于检查重复列表的方案函数
【发布时间】:2012-03-23 21:54:11
【问题描述】:

我需要编写一个 Scheme 函数来检查列表中的重复条目。我想我已经把工作流程写在纸上了,我只需要帮助把它从纸上写成代码。

首先我需要检查它是否是一个空列表。所以我有...

(define (checkDupe mylist)
  (if (null? mylist)
      ()
      (checkDupeB mylist)
  )
)

然后我有这种“双重递归”,我将第一个数字与列表的其余部分检查,然后将第二个数字与列表的其余部分检查,依此类推,当找到匹配项时它会吐出一个#t,如果它到达末尾并且没有找到匹配,函数的结果是#f。问题是我无法理解这个递归的东西。这是一个家庭作业问题,但我对学习这些东西非常感兴趣。

有人可以向我扔一些代码并帮助我解决这个问题吗?

【问题讨论】:

  • 您可能想看看如何设计程序的草案,第 2 版,尤其是从第 4 章开始:ccs.neu.edu/home/matthias/HtDP2e/htdp2e-part2.html。该章介绍了如何有条不紊地处理这类列表问题。
  • 要理解递归,你只需要理解计数。我们用自然数来计算。什么是自然数?它要么是 0,要么比自然数大一。 imagine you're a wizard 在炎热干旱的沙漠中。你知道附近每个城市的方向;你决定怎么去?你想找到最近的。你怎么能知道到一个城市的距离而不实际去那里?你是个巫师;你创建一个自己的副本,离那个城市更近一步,然后向寻求答案。因为他也是一个巫师,所以他重复这个过程。

标签: list recursion duplicates scheme workflow


【解决方案1】:

这是一种方式

(define (has-duplicates? lst) 
  (cond
     [(empty? lst) #f] 
     [(not (not (member (first lst) (rest lst)))) #t]
     [else (has-duplicates? (rest lst)) ])) 

【讨论】:

    【解决方案2】:

    我猜这是家庭作业。这是一个简单的过程,但您的导航流程中缺少一个案例,因为需要考虑三个案例:

    1. 如果列表为空怎么办?这意味着其中没有任何重复项
    2. 如果列表的当前元素存在于列表的其余部分中,会发生什么情况?那么这意味着列表中有重复项(提示:member 过程可能有用)
    3. 如果以上都不成立,继续下一个元素

    作为进一步的帮助,以下是总体思路,请填空:

    (define (checkDupe mylist)
      (cond ((null? myList) ???) ; case 1
            (??? #t)             ; case 2
            (else ???)))         ; case 3
    

    【讨论】:

      【解决方案3】:

      为每个成员再次遍历整个列表以检查重复项可能会很昂贵 - O(n^2)。检查相邻重复项要便宜得多——O(n)。如果您不介意更改列表中元素的顺序,则可以通过首先对列表进行排序来使所有重复项相邻。该列表必须由可以通过某些 > 运算符进行比较的元素组成。

      (define (remove-duplicates xs)
        (fold-right cons-if-not-duplicate '() (sort xs >)))
      

      这种方法的一个优点是它依赖于标准折叠运算符而不是自定义递归。由于这是家庭作业,我省略了cons-if-not-duplicate 的定义。

      【讨论】:

        【解决方案4】:

        解决问题的方法不止一种。这是建议。

        1. 编写一个辅助函数(is-element-in-list?x l), 如果 x 在列表 l 中,则返回 true,否则返回 false。

        2. 填空

          (define (contains-duplicate? l)
             (cond [(list? l) (or <check whether (first l) is in (rest l)>
                                  <check where (rest l) contains a duplicate> )
                   [else false]))
          

        【讨论】:

          【解决方案5】:

          这是我的解决方案,虽然未经测试应该可以工作,

          (define rmdup
             (lambda list
                (cond
                   ((null? list) '())
                   ((eq? (car list) (car (cdr list)) (rmdup(cdr list)))
                    (else( cons (car list) (rmdup(cdr list)))))))
          

          算法大声说出来: 如果第一辆车等于下一辆车?砍掉初始然后再去,否则,保留它,然后继续。这样我们只保留唯一的副本,而不是任何有邻居兄弟的东西

          【讨论】:

          • 我修正了你的格式,但我认为这不起作用。 (提示:(rmdup '(1 2 3 1)) 返回什么?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-11
          • 1970-01-01
          • 2019-02-11
          • 2023-03-26
          • 2017-01-29
          • 1970-01-01
          相关资源
          最近更新 更多