删除列表中的重复元素

时间:2015-10-15 17:04:01

标签: list scheme racket

我很感激有人帮忙交到这里。我正在尝试构建一个删除列表中重复元素的过程。这部分很容易。但是我还想删除重复的元素(也可能是列表),如果它是一个列表,那么该列表中的重复元素也应该删除,例如(make-set(list 1 2 3 2(list 1 3 2 4) 3 4)(列表1 3 2 4 3 4)))应为'(1 3 2(1 2 3 4))但在我们的情况下它变为'(1 3 2 2 3 4)。这不是我们想要的。我究竟做错了什么?谢谢:))

;; Checks if an element x appears in a list (set)
(define (element-of-set? x set)
  (cond (( null? set) false)
        ((equal? x (car set)) true)
        (else (element-of-set? x (cdr set)))))

;; Delete duplicated elements of a list (set)
(define make-set
  (lambda (lst)
    (cond ((null? lst) '())
          ((if (list? (car lst))
               (cond ((null? (car lst))
                      '()
                      )
                     ((element-of-set? (caar lst) (car lst)) (make-set (cdar lst))
                                                              )
                     (else (cons (caar lst) (make-set cadr lst))))
               (cond ((element-of-set? (car lst) (cdr lst)) (make-set (cdr lst)))
                     (else (cons (car lst) (make-set (cdr lst))))))))))

2 个答案:

答案 0 :(得分:1)

make-set的规范有点不清楚,但也许这对您有用:

(define make-set
  (lambda (lst)
    (cond ((null? lst)                            '())
          ((list? (car lst))                      (cons (make-set (car lst)) (make-set (cdr lst))))
          ((element-of-set? (car lst) (cdr lst))                             (make-set (cdr lst)))
          (else                                   (cons (car lst)            (make-set (cdr lst)))))))

请注意,使用lst并不常用。

一个不错的约定是使用x作为列表中的元素,并使用xs作为x元素列表。

答案 1 :(得分:1)

实际上,如果你想构建一个函数;; check if x is contained in set (define (contained? x set) (cond ((null? set) false) ((my-equal? x (car set)) true) (else (contained? x (cdr set))))) ;; check if all the elements of set1 are contained in set2 (define (set-contained? set1 set2) (cond ((null? set1) true) ((null? set2) false) (else (and (contained? (car set1) set2) (set-contained? (cdr set1) set2))))) ;; check if set1 is equal to set2 (define (set-equal? set1 set2) (and (= (length set1) (length set2)) (set-contained? set1 set2))) ;; check if x1 is equal to x2, when x1 and x2 can be sets or elements (define (my-equal? x1 x2) (cond ((list? x1) (and (list? x2) (set-equal? x1 x2))) ((list? x2) false) (else (eq? x1 x2)))) ;; add the element x to set, if not already present (define (add-to-set x set) (cond ((null? set) (list x)) ((my-equal? x (car set)) set) (else (cons (car set) (add-to-set x (cdr set)))))) ;; make a set from a list lst (define (make-set lst) (cond ((null? lst) '()) ((list? (car lst)) (add-to-set (make-set (car lst)) (make-set (cdr lst)))) (else (add-to-set (car lst) (make-set (cdr lst)))))) (make-set (list 1 2 3 2 (list 1 3 2 4 3 4) (list 1 3 2 4 3 4))) ; => '(1 3 (1 2 3 4) 2) 来管理一个通用的,无类型的set概念(这是一个可以包含数字或递归其他集合的集合),那么定义就非常复杂。这是我的尝试。

make-set

函数set通过在新集合中依次插入原始列表的每个元素来构建集合,以便检查元素是否已经存在(同样,如果元素是列表,首先它是转换成一套)。鉴于以下惯例,其他功能应易于理解:

  1. 如果一个参数被调用x,该函数需要一个已经表示为set的列表。
  2. 如果参数被称为{{1}},则它可以是数字或集合。