删除列表中的重复元素
Delete duplicated elements in a list
我很感激您的帮助。我正在尝试构建一个删除列表中重复元素的过程。这部分很简单。但是后来我也想删除重复的元素(也可能是列表),如果它是一个列表,那么也应该删除该列表中的重复元素,例如(make-set(list 1 2 3 2(list 1 3 2 4 3 4) (list 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))))))))))
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 元素列表。
实际上,如果您想构建一个函数 make-set
来管理广义的、无类型的集合概念(即可以包含数字或递归地包含其他集合的集合),则定义非常复杂。这是我的尝试。
;; 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)
函数make-set
通过依次将原始列表的每个元素插入新集合来构建集合,因此要检查元素是否已经存在(另外,如果元素是列表,首先它被转换成一个集合)。给定以下约定,其他功能应该很容易理解:
- 如果调用参数
set
,该函数需要一个已表示为集合的列表。
- 如果一个参数被称为
x
,那么它要么是一个数字,要么是一个集合。
我很感激您的帮助。我正在尝试构建一个删除列表中重复元素的过程。这部分很简单。但是后来我也想删除重复的元素(也可能是列表),如果它是一个列表,那么也应该删除该列表中的重复元素,例如(make-set(list 1 2 3 2(list 1 3 2 4 3 4) (list 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))))))))))
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 元素列表。
实际上,如果您想构建一个函数 make-set
来管理广义的、无类型的集合概念(即可以包含数字或递归地包含其他集合的集合),则定义非常复杂。这是我的尝试。
;; 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)
函数make-set
通过依次将原始列表的每个元素插入新集合来构建集合,因此要检查元素是否已经存在(另外,如果元素是列表,首先它被转换成一个集合)。给定以下约定,其他功能应该很容易理解:
- 如果调用参数
set
,该函数需要一个已表示为集合的列表。 - 如果一个参数被称为
x
,那么它要么是一个数字,要么是一个集合。