我如何检查列表是否有不同的对象(是一组?)或不是Scheme

时间:2018-04-26 17:21:19

标签: scheme racket

我正在尝试在方案中编写一个函数,即检查列表是否为一组。

在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
        }
    }
}
(define set? (lambda (lst)

))

3 个答案:

答案 0 :(得分:0)

您使用[球拍]标签,因此我假设您正在使用球拍。您可以使用库函数check-duplicates来检查重复元素。您可以使用remove-duplicates删除它们。

答案 1 :(得分:0)

我假设您想要知道如何执行此操作,例如,如果语言没有设置数据类型(Racket所做的那样)和一堆处理集合的工具,包括处理列表作为集合。因此,让我们重新发明已经存在的东西,从一个函数开始,告诉你列表中是否有某些东西(在现实生活中这是一堆名为member的函数):

(define (occurs? e l (test? eqv?))
  ;; does e occur in l, testing with test?
  (cond [(null? l)
         ;; empty lists have no members
         #f]
        [(test? e (first l))
         ;; if e is the first element of l then it's in l
         #t]
        [else
         ;; if e is in the rest of l it's in l
         (occurs? e (rest l) test?)]))

现在,您可以回答关于列表是否为集合的问题。列表是一个集合if:

  • 这是空名单;
  • 列表的第一个元素不会出现在列表的其余部分,列表的其余部分是一个集合。

此规范可以直接转换为代码:

(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?))))

答案 2 :(得分:0)

基本上你正在做的是有两个游标。 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) 的是什么?这是一个递归函数。以上内容与:

相同
int fori (int i) {
  return i >= count - 1 ||
         forj(i, i+1) && fori(i+1); 
}

int forj (int i, int j) {
  return j >= count || 
        array[i] == array[j] && forj(i, j+1);
}

int result = fori(0);

如果您可以使用递归编写C解决方案,可能会更容易一些?例如。

{{1}}