Scheme 如何检查列表是否具有不同的对象(是否为集合?)

Scheme 如何检查列表是否具有不同的对象(是否为集合?),scheme,racket,Scheme,Racket,我试图在scheme中编写一个函数,检查列表是否为集合 在C语言中,算法如下: int count = sizeof(array) / sizeof(array[0]); for (int i = 0; i < count - 1; i++) { for (int j = i + 1; j < count; j++) { if (array[i] == array[j]) { //return false }

我试图在scheme中编写一个函数,检查列表是否为集合

在C语言中,算法如下:

int count = sizeof(array) / sizeof(array[0]);

for (int i = 0; i < count - 1; i++) { 
    for (int j = i + 1; j < count; j++) {
        if (array[i] == array[j]) {
            //return false
        }
    }
}

你使用[racket]标签,所以我假设你使用的是racket。可以使用库函数检查重复的元素。您可以使用来删除它们。

我假设您想知道,如果该语言没有一个集合数据类型(Racket有)和一系列处理集合的工具,包括将列表作为集合处理,您将如何做到这一点。因此,让我们重新设计已经存在的东西,从一个函数开始,该函数告诉您列表中是否发生了什么(在现实生活中,这是一组名为
member
)的函数:

现在你可以回答列表是否是集合的问题。列表是一个集合,如果:

  • 它是空的列表
  • 列表的第一个元素不会出现在列表的其余部分,列表的其余部分是一个集合
本规范可直接转换为代码:

(define (list-set? l (test? eqv?))
  ;; is l a set?
  (if (null? l)
      ;; the empty list is a set
      #t
      ;; otherwise it is a set if ...
      (and
       ;; .. the first element of it does not occur in the rest of it ...
       (not (occurs? (first l) (rest l) test?))
       ;; ... and the rest of it is a set
       (list-set? (rest l) test?))))

基本上你要做的是有两个游标
i
从开始到最后一个元素,对于每个元素,
j
i
开始到最后一个元素

下面是如何创建循环:

(let name ((var 0) (var2 5))
  (if (> var var2)
      var
      (name (+ (* 2 var) 1) (+ var2 1))))
因为我们在这里讨论的是列表,列表是
cons
链,而不是索引,所以您只需使用单个
cons
的绑定进行迭代:

(define test '(1 2 3 4 5 6 7 8))
(let find-half ((hare test) (tortoise test))
  (if (or (null? hare)
          (null? (cdr hare)))
      tortoise
      (find-half (cddr hare) (cdr tortoise))))
那么什么是命名的
let
?这是一个递归函数。以上内容同:

(define test '(1 2 3 4 5 6 7 8))
(define (find-half hare tortoise)
  (if (or (null? hare)
          (null? (cdr hare)))
      tortoise
      (find-half (cddr hare) (cdr tortoise))))
(find-half test test)
如果你能用递归编写你的C解决方案可能会更容易些?例如

intfori(inti){
返回i>=计数-1||
forj(i,i+1)和fori(i+1);
}
int forj(int i,int j){
返回j>=计数||
数组[i]==数组[j]&forj(i,j+1);
}
int结果=fori(0);

使用
count
作为最大的有效数组索引,表明最小的有效数组索引为1。@WillNess good catch。我想要的是
I
的倒数,当然就是
I>=count
:)
(define test '(1 2 3 4 5 6 7 8))
(let find-half ((hare test) (tortoise test))
  (if (or (null? hare)
          (null? (cdr hare)))
      tortoise
      (find-half (cddr hare) (cdr tortoise))))
(define test '(1 2 3 4 5 6 7 8))
(define (find-half hare tortoise)
  (if (or (null? hare)
          (null? (cdr hare)))
      tortoise
      (find-half (cddr hare) (cdr tortoise))))
(find-half test test)