2016-03-05 64 views
-1

我是计划的新手。我正在尝试使用方案查找列表的最大值和最小值。使用“循环”我能够得到答案。现在我正在尝试不同的方式来实现同样的事情。我做了一些改变,出于某种原因,我找不到我做错了什么。如何使用方案编写计算整数列表的最大值和最小值的函数

;non working version 
    (define (min-max list1) 
    (let (ls list1) (max (car list1)) (min(car list1)) 
     (cond 
     ((null? ls) 
       (list "max: " max "min: " min)) 
     ((> (car ls) max) 
      (let ((car ls) max)) 
      (min-max (cdr ls))) 
     ((< (car ls) min) 
      (let ((car ls) min)) 
       (min-max (cdr ls))) 
     (else 
       (min-max (cdr ls)))))) 
    (define list1(list 1 2 3 4)) 
    (display list1) 
    (newline) 
    (min-max list1) 

    ;working version 
    (define (min list1) 
     (let loop((ls list1) (max (car list1)) (min(car list1))) 
     (cond 
     ((null? ls) 
       (list "max: " max "min: " min)) 
      ((> (car ls) max) 
      (loop (cdr ls)(car ls) min)) 
     ((< (car ls) min) 
      (loop (cdr ls) max (car ls))) 
     (else 
       (loop (cdr ls) max min))))) 

     (define list1(list 1 2 3 4)) 

     (display list1) 
     (newline) 
     (min list1) 
+1

这段代码有太多的错误,我不知道从哪里开始。错误的语法,括号错误,不正确的函数调用,不存在的过程......我建议你先阅读一本关于Scheme的良好教科书,对不起。 –

+0

感谢您的回复。我试图从在线教程学习计划。我在上面添加了一个工作版本。我试图找到在条件语句之后是否有任何方式运行多个表达式。如果你能指导我使用任何合适的材料,请告诉我。谢谢你的时间。 –

+0

请注意,在工作版本中有一个名为'let'(您称之为'loop')。它会创建一个包含变量名称的过程,以便在浏览列表时可以保持最小值。在你试图做min和max时,你需要以当前结果作为变量以相同的方式。 – Sylwester

回答

1

这不是代码审查,但我会先从您的过程的“工作”版本开始。由于这个过程不适用于空列表,所以你应该为它添加一个测试。然后,不需要重新比较列表的第一个元素minmax。然后,您似乎认为loop是一个关键字,所以我将其名称更改为helper。最后,我已经修改了它要少重复:

(define (min-max lst) 
    (if (null? lst) 
     '() 
     (let helper ((lst (cdr lst)) (min (car lst)) (max (car lst))) 
     (if (null? lst) 
      (list min max) 
      (let ((c (car lst))) 
       (helper (cdr lst) 
         (if (< c min) c min) 
         (if (> c max) c max))))))) 

这是一样的

(define (min-max lst) 
    (define (helper lst min max) 
    (if (null? lst) 
     (list min max) 
     (let ((c (car lst))) 
      (helper (cdr lst) 
        (if (< c min) c min) 
        (if (> c max) c max))))) 
    (if (null? lst) 
     '() 
     (helper (cdr lst) (car lst) (car lst)))) 

测试:

> (min-max '(1 2 3 4)) 
'(1 4) 
> (min-max '(1 8 2 3 4)) 
'(1 8) 
> (min-max '()) 
'() 

你的第一个过程不因为在每个工作递归调用您重新初始化minmax。另外,由于没有空白列表的测试,所以不可避免地最终会得到空列表的car,这在Scheme中是不允许的。最后,它看起来像要在递归调用之外更改minmax的值,这意味着您必须使用set!。这里有一个工作版本:

(define (min-max lst) 
    (if (null? lst) 
     '() 
     (let ((min (car lst)) (max (car lst))) 
     (define (helper lst) 
      (if (null? lst) 
       (list min max) 
       (let ((c (car lst))) 
       (when (< c min) (set! min c)) 
       (when (> c max) (set! max c)) 
       (helper (cdr lst))))) 
     (helper lst)))) 

这将产生相同的结果,但你可以看到代码是如何少得多优雅的外观与set!相比,递归调用helper

+0

为什么在通过空列表时不能失败?由于没有数字的空白列表的最小值和最大值,因此IMO评估为零会使问题远离即将出现的错误的来源。 – Sylwester

+0

@Sylwester好吧,我想我们不同意这一点;-) – uselpa

+1

@uselpa非常感谢。你的回答澄清了我的困惑。 –

相关问题