返回其列表参数中最短参数的Scheme函数

返回其列表参数中最短参数的Scheme函数,scheme,racket,Scheme,Racket,我正在尝试创建一个scheme函数,该函数将返回其参数列表中最短的参数 (最短的"1 2"(2 3 4)(4)(5 6 7 8))应编译(4) 这就是我目前所拥有的 (define (shortest lst) (foldl (lambda (e r) (if (or (not r) (< e r)) e r)) #f lst)) (定义(最短lst)(foldl(lambda(Er)(如果(或(非r)(

我正在尝试创建一个scheme函数,该函数将返回其参数列表中最短的参数

(最短的"1 2"(2 3 4)(4)(5 6 7 8))应编译(4)

这就是我目前所拥有的

(define (shortest lst) (foldl (lambda (e r) (if (or (not r) (< e r)) e r))
     #f
     lst))
(定义(最短lst)(foldl(lambda(Er)(如果(或(非r)(

它给出了错误的算术不匹配。

您的函数只有一个名为
lst
的参数,但您可以在可变数量的列表上调用它。因此,您应该决定您希望哪种输入:

  • 名单
  • (定义(最短lst)
    (如果(空?lst)lst
    (车辆(分类lst)
    (λ(l1-l2)
    (<(长度l1)(长度l2(()())))
    ((12)(23 4)(4)(5 6 7 8))
    (最短的“())
    
  • 列表数量可变
  • (定义(最短的.args)
    (如果(空?args)args
    (车辆(分拣args)
    (λ(l1-l2)
    (<(长度l1)(长度l2(()())))
    (12)(2 3 4)(4)(5 6 7 8)
    (最短的“())
    
    您的答案几乎是正确的,但您需要实际比较子列表的长度,并确保您的过程接受可变数量的参数。这应该是可行的,变化最小:

    ; the . is for accepting multiple args
    (define (shortest . lst)
      (foldl (lambda (e r)
               ; notice how we compare the lengths
               (if (or (not r) (< (length e) (length r))) e r))
             #f
             lst))
    

    一个有趣的问题是:你能在不考虑所有列表长度的情况下解决这个问题吗?如果你有一个包含一百万个元素的列表和一个包含四个元素的列表,你真的需要计算这个巨大列表的长度才能知道答案吗

    答案是不,你没有。有一种方法可以做到这一点:

    (define (shortest . args)
      (define (step tail-pairs new-tail-pairs)
        ;; step has a list of pairs of tail & original-list pairs it is looking at,
        ;; and another list of pairs of (cdr tail) & original-list which it will
        ;; look at on the next cycle.
        (if (null? tail-pairs)
            ;; Run out of things to look at, start on the next cycle
            (step new-tail-pairs '())
            (let ((this-tail-pair (first tail-pairs))
                  (more-tail-pairs (rest tail-pairs)))
              (if (null? (car this-tail-pair))
                  ;; found it: nothing left in this list so return the original
                  ;; list
                  (cdr this-tail-pair)
                  ;; Not empty: add this tail pair with its first element removed to
                  ;; the next cycle list, and loop on the remains of this cycle
                  (step more-tail-pairs (cons (cons (cdr (car this-tail-pair))
                                                    (cdr this-tail-pair))
                                              new-tail-pairs))))))
      ;; build the initial list of tail pairs and start stepping down it.
      (step (map cons args args) '()))
    
    ; the . is for accepting multiple args
    (define (shortest . lst)
      (foldl (lambda (e r)
               ; notice how we compare the lengths
               (if (or (not r) (< (length e) (length r))) e r))
             #f
             lst))
    
    (shortest '(1 2) '(2 3 4) '(4) '(5 6 7 8))
    => '(4)
    
    (shortest '())
    => '()
    
    (shortest)
    => #f
    
    (define (shortest . args)
      (define (step tail-pairs new-tail-pairs)
        ;; step has a list of pairs of tail & original-list pairs it is looking at,
        ;; and another list of pairs of (cdr tail) & original-list which it will
        ;; look at on the next cycle.
        (if (null? tail-pairs)
            ;; Run out of things to look at, start on the next cycle
            (step new-tail-pairs '())
            (let ((this-tail-pair (first tail-pairs))
                  (more-tail-pairs (rest tail-pairs)))
              (if (null? (car this-tail-pair))
                  ;; found it: nothing left in this list so return the original
                  ;; list
                  (cdr this-tail-pair)
                  ;; Not empty: add this tail pair with its first element removed to
                  ;; the next cycle list, and loop on the remains of this cycle
                  (step more-tail-pairs (cons (cons (cdr (car this-tail-pair))
                                                    (cdr this-tail-pair))
                                              new-tail-pairs))))))
      ;; build the initial list of tail pairs and start stepping down it.
      (step (map cons args args) '()))