获取方案列表中的最大数字

时间:2014-11-25 14:12:17

标签: scheme racket

我不明白为什么我的函数获取最大数字不想工作。如果我正确地考虑这个问题,如果第一个原子小于第二个原子,那么你调用函数减去列表中的第一个原子,否则你用列表的其余部分构造第一个原子,最大的原子。相关代码:

(define (getlargest a_list)
  (cond
    ((null? a_list) '())
    ((< (car a_list) (cadr a_list)) (getlargest (cdr a_list)))
    (else (cons (car a_list) (getlargest(cdr a_list))))))

7 个答案:

答案 0 :(得分:4)

您当前的程序在运行时失败。即使它没有,你也要将一个元素与下一个元素进行比较,但这对于找到一个最大值是不行的,例如在这样的列表中它会返回{{ 1}},这是不正确的:1。还有其他错误,例如 - 当答案应该是数字时,为什么要将列表构建为输出?你也必须非常小心边缘情况,当列表中只剩下一个元素时,你的程序就会失败。

正确的方法是将假设为最大的一个元素与所有其余元素进行比较,如果我们找到一个大于假定最大值的元素,那么我们就找到了一个新的最大值。这就是我的意思:

'(10 2 0 1)

当然,在现实生活中,我们会使用内置的(define (getlargest a_list) (if (null? a_list) ; edge case: empty list #f ; return a special value signaling error (let loop ((a_list (cdr a_list)) ; rest of the list (maxval (car a_list))) ; assumed maximum (cond ((null? a_list) maxval) ; if the list is empty, return max ((> (car a_list) maxval) ; current element > max (loop (cdr a_list) (car a_list))) ; found new max (else ; otherwise (loop (cdr a_list) maxval)))))) ; keep the same max 程序来达到同样的目的:

max

答案 1 :(得分:4)

没有任何循环,使用递归:

(define (maximum L)
     (if (null? (cdr L)) 
         (car L) 
         (if (< (car L) (maximum (cdr L)))  
             (maximum (cdr L)) 
             (car L)
         )
    )
)

答案 2 :(得分:2)

您的代码中有2个错误:

1)在else子句中,你应该递归调用自己,删除第二个元素:

(else (getlargest (cons (car a_list) (cddr a_list))))))

2)您错过了仅包含一个元素的列表的情况,其中cadr将失败

((null? (cdr a_list)) (car a_list))

如果列表为空,我个人更愿意屈服#f。因此代码看起来像

(define (getlargest a_list)
  (cond
    ((null? a_list)       
     #f)
    ((null? (cdr a_list))
     (car a_list))
    ((< (car a_list) (cadr a_list))
     (getlargest (cdr a_list)))
    (else 
     (getlargest (cons (car a_list) (cddr a_list))))))

当然,使用foldl的解决方案更可取:

(define (getlargest lst)
  (foldl (lambda (e r) (if (or (not r) (> e r)) e r))
         #f
         lst))

或者,效率可能略高:

(define (getlargest lst)
  (if (null? lst)
      #f
      (foldl (lambda (e r) (if (> e r) e r))
             (car lst)
             (cdr lst))))

答案 3 :(得分:1)

(define (maxim lst)
  (vector-argmax (lambda (x) x) (list->vector lst)))

答案 4 :(得分:0)

(define (max-list-element list)
  (define (aux list actual-max)
    (if (pair? (cdr list))
        (if (>= (car list) actual-max)
            (aux (cdr list) (car list))
            (aux (cdr list) actual-max))
        (if (> (car list) actual-max)
        (car list)
        actual-max)))
  (aux list (car list)))

我的实现。

答案 5 :(得分:0)

第一个错误是在基本情况下您要返回列表作为输出。您需要返回一个数字。 您可以通过在列表进行递归时将最大值存储在MaxVal累加器中,以递归方式实现此过程。

规格

输入:正唯一编号inList

的列表

输出:列表MaxVal

中的最大值

以下是上述规范的实现:

过程

(define (GetMaxVal MaxVal inList) 
    (cond ( (null? inList ) MaxVal )
          ( (> (car inList) MaxVal ) (GetMaxVal (car inList) (cdr inList)) ) 
          ( else ( GetMaxVal MaxVal (cdr inList)) ) ))

(define inList '(1 67 3 5 176 4745 34 575)) 

(display (GetMaxVal 0  inList) ) ; prints 4745 to screen

说明

  1. 如果列表为空,我们已经达到基本情况,因此返回MaxVal
  2. 如果列表中的第一个元素大于MaxVal,则大于更新MaxVal;在递归调用中将MaxVal(cdr inList)传递给参数。
  3. else的第一个元素不大,因此通过传递没有第一个元素的list来递归,即(cdr inList)

答案 6 :(得分:0)

;; ListOfNum Number -> Number
(define (list-maximum-core lon max)
  (cond
    [(empty? lon) max]   ; base case
    [else
      (list-maximum-core (rest lon) (if (> (first lon) max) (first lon) max) )] ))

;; ListOfNum -> Number
(define (list-maximum-main lon)
  (list-maximum-core lon 0) )
  • 调用list-maximum-core函数时,使max=0作为max的初始值
  • 在列表的每个递归循环中,我们检查列表中的第一项是否大于 max;如果是,则将此值传递给 max 变量;如果不是,则最大变量值不会改变
  • 在每个递归循环中,列表中的第一项被移除并且列表变小;这一直持续到列表为空,此时它输出当时 max 的任何值(当基本情况为真时)
  • 为了避免每次调用函数时都添加 0 作为第二个变量的不便,我们创建了 list-maximum-main 函数