Scheme 删除方案中嵌套列表中的重复项

Scheme 删除方案中嵌套列表中的重复项,scheme,Scheme,我试图在Scheme中编写一个函数makeset,它接受一个列表,可能包含列表,并删除所有重复项。例如,makeset'12323应返回1233,makeset'1233应返回1233。这是我目前的代码: (define make-set (lambda (lst) (cond ((empty? lst) lst) ((not (list? lst)) (list lst)) ((member? (car lst) (cdr lst))

我试图在Scheme中编写一个函数makeset,它接受一个列表,可能包含列表,并删除所有重复项。例如,makeset'12323应返回1233,makeset'1233应返回1233。这是我目前的代码:

(define make-set
  (lambda (lst)
    (cond ((empty? lst) lst)
          ((not (list? lst)) (list lst))
          ((member? (car lst) (cdr lst))
           (cons (car lst)
                   (make-set (delete (car lst) (cdr lst)))))
          ((list? (car lst))
           (cons (make-set (car lst))
                   (make-set (cdr lst))))
          ((equal? (set-len lst) 1)
           lst)
          (else (cons (car lst) (make-set (cdr lst)))))))
这对我提到的案例有效。但是,例如,如果我编写makeset'1,我会得到答案11,因此它会创建新的副本。不知怎的,我想说,如果仍然有重复的,它应该再次运行该函数,但我不知道如何运行


我在makeset中使用的其他函数是member?检查可作为列表的元素是否在另一个列表中,删除可从列表中删除所有可作为列表的元素,并设置len以返回列表的长度。

您还没有真正指定在列表的不同级别应该发生什么,例如,如果从2到3开始,但是对于您指定的情况,下面的方法是有效的。其思想是在每个级别上展平元素,然后删除重复的元素。不过,称这个makeset有点用词不当,因为它并不是你想要取回的一套。否则,1可能会返回1,因为11与1不同。也就是说,这段代码适用于您展示的示例

(define (remove-duplicates list)
  (if (null? list)
      list
      (let ((tail (remove-duplicates (cdr list))))
        (if (member (car list) tail)
            tail
            (cons (car list) tail)))))

(define (make-set tree)
  (if (not (pair? tree))
      tree
      (remove-duplicates (map make-set tree))))

我同意Joshua的观点,应该修改算法以避免陷入那种情况。但我首先要回答你提出的问题:不知何故,我想说,如果仍然存在重复项,它应该再次运行该函数,但我不知道如何运行

实际上这很简单:只需循环,直到结果与您传递的列表相同:

(define make-full-set
  (lambda (lst)
    (let ((r (make-set lst)))
      (if (equal? r lst)
          r
          (make-full-set r)))))
测试:

> (make-full-set '((1 1) (1 1 1)))
'((1))
> (make-set '((1 1) (1 1 1)))
'((1))
> (make-set '(2 (2 3)))
'(2 (3))
> (make-set '(2 (2 3)))
'(2 (3))
当然,这是笨拙和低效的需要一个额外的过程,和昂贵的列表比较,所以我们真的需要一个更好的算法。根据我的解释,我的观点是,所有原子都应该是唯一的:

(define (make-set lst)

  (define (sub lst items res)
    (if (null? lst)
        (values items (reverse res))
        (let ((c (car lst)))
          (cond
            ((list? c) (let-values (((items2 res2) (sub c items '())))
                         (sub (cdr lst) items2 (if (null? res2) res (cons res2 res)))))
            ((member c items) (sub (cdr lst) items res))
            (else             (sub (cdr lst) (cons c items) (cons c res)))))))

  (let-values (((_ res) (sub lst '() '()))) res))
测试:

> (make-full-set '((1 1) (1 1 1)))
'((1))
> (make-set '((1 1) (1 1 1)))
'((1))
> (make-set '(2 (2 3)))
'(2 (3))
> (make-set '(2 (2 3)))
'(2 (3))

什么能让set'1 2 3 2 4回归?既然我们为您花费了我们的空闲时间,我们将非常感谢您的反馈!