查找列表的最小值和最大值
Finding min and max of list
(define (find-extrema-helper xs max min length)
(if (null? xs)
(printf "The maximum of your list is ~a and the minimum is ~a." max min)
(let ((head (car xs))
(tail (cdr xs)))
(when (> head max)
(set! max head))
(when (< head min)
(set! min head))
(when (not (null? length))
(set! length (- length 1)))
(when (equal? length 0)
(set! xs null))
(find-extrema-helper tail max min length))))
(define (find-extrema xs)
(let ((max (car xs))
(min (car xs)))
(find-extrema-helper xs max min null)))
(define (find-extrema-sublist-helper xs first length)
(if (> first 0)
(let ((head (car xs))
(tail (cdr xs))
(first (- first 1)))
(find-extrema-sublist tail first length))
(let ((max (car xs))
(min (car xs)))
(find-extrema-helper xs max min length))))
(define (find-extrema-sublist xs first last)
(set! last (- last first))
(find-extrema-sublist-helper xs first last))
一切正常,除了在查找子列表的最大值时,就像长度变量被忽略并且正在查找整个列表的最大值。感谢您的帮助。
试试这个:
(define (find-extrema xs)
(if (null? xs) "Empty list."
(printf "The maximum of your list is ~a and the minimum is ~a."
(apply max xs)
(apply min xs))))
- 如果您的函数需要列表作为参数,则此列表可以为空。 null? returns #true,如果 xs 是空列表。
(null? '()) => #t
.
- 如果您需要将某个数字与零进行比较,请改用
(= 0 number)
。
- 方案具有内置函数 min and max,但您不能在列表中使用它们:
(max 1 2 3 4 5) => 5
、(max '(1 2 3 4 5)) => error
。
- 但是 apply 正是您所需要的。
(apply max '(1 2 3 4 5)) => (max 1 2 3 4 5) => 5
.
- 顺便说一句,当您命名变量时,请检查该名称是否尚未被使用(例如 min、max , length, first, last)。在 REPL 中输入该名称并查看结果:
max => #<procedure:max>
。 Scheme 允许您在给定范围内更改该变量的值,但您将丢失以前的值。比较这两个函数:
(define (f1 xs first)
(first xs))
(define (f2 xs first-elem)
(first xs))
,这样称呼:
> (f1 '(1 2 3) 1)
> (f2 '(1 2 3) 1)
编辑:没有内置最小值和最大值的解决方案:
(define (find-extrema-help xs min-num max-num)
(if (null? xs)
(printf "The maximum of your list is ~a and the minimum is ~a." max-num min-num)
(find-extrema-help (cdr xs)
(if (< (car xs) min-num) (car xs) min-num)
(if (> (car xs) max-num) (car xs) max-num))))
(define (find-extrema xs)
(if (null? xs) "Empty list."
(find-extrema-help (cdr xs)
(car xs)
(car xs))))
查找极值子列表:
(define (drop xs number)
(cond ((null? xs) xs)
((= 0 number) xs)
(else (drop (cdr xs) (- number 1)))))
(define (take xs number)
(cond ((null? xs) '())
((= number 0) '())
(else (cons (car xs) (take (cdr xs) (- number 1))))))
(define (find-extrema-sublist xs down-index top-index)
(let ((len (- top-index down-index)))
(find-extrema (take (drop xs down-index)
len))))
您几乎从不需要“设置!”,并且您应该递归列表的结构,而不是它的长度。
对于非空列表,最大值为
car
,如果列表只有一个元素(即它的尾部是空列表),
car
中的最大值和 cdr
中的最大值,如果列表更长。
即
(define (max-element x y) (if (> x y) x y))
(define (max-list ls)
(if (null? (cdr ls))
(car ls)
(max-element (car ls) (max-list (cdr ls)))))
同样的原则也适用于最小值。
(define (min-element x y) (if (< x y) x y))
(define (min-list ls)
(if (null? (cdr ls))
(car ls)
(min-element (car ls) (min-list (cdr ls)))))
现在你需要两者,所以你应该制作一对(或其他一些结构)。
简单的方法是使用前面的两个函数,
(define (extrema ls) (cons (min-list ls) (max-list ls)))
但这很低效,因为它遍历了列表两次。
让我们做得更好。
这是同时应用于两个值的相同想法:
(define (extrema ls)
(if (null? (cdr ls))
(cons (car ls) (car ls))
(let ((cdr-extrema (extrema (cdr ls)))
(head (car ls)))
(cons (min-element head (car cdr-extrema))
(max-element head (cdr cdr-extrema)))))
(define (find-extrema-helper xs max min length)
(if (null? xs)
(printf "The maximum of your list is ~a and the minimum is ~a." max min)
(let ((head (car xs))
(tail (cdr xs)))
(when (> head max)
(set! max head))
(when (< head min)
(set! min head))
(when (not (null? length))
(set! length (- length 1)))
(when (equal? length 0)
(set! xs null))
(find-extrema-helper tail max min length))))
(define (find-extrema xs)
(let ((max (car xs))
(min (car xs)))
(find-extrema-helper xs max min null)))
(define (find-extrema-sublist-helper xs first length)
(if (> first 0)
(let ((head (car xs))
(tail (cdr xs))
(first (- first 1)))
(find-extrema-sublist tail first length))
(let ((max (car xs))
(min (car xs)))
(find-extrema-helper xs max min length))))
(define (find-extrema-sublist xs first last)
(set! last (- last first))
(find-extrema-sublist-helper xs first last))
一切正常,除了在查找子列表的最大值时,就像长度变量被忽略并且正在查找整个列表的最大值。感谢您的帮助。
试试这个:
(define (find-extrema xs)
(if (null? xs) "Empty list."
(printf "The maximum of your list is ~a and the minimum is ~a."
(apply max xs)
(apply min xs))))
- 如果您的函数需要列表作为参数,则此列表可以为空。 null? returns #true,如果 xs 是空列表。
(null? '()) => #t
. - 如果您需要将某个数字与零进行比较,请改用
(= 0 number)
。 - 方案具有内置函数 min and max,但您不能在列表中使用它们:
(max 1 2 3 4 5) => 5
、(max '(1 2 3 4 5)) => error
。 - 但是 apply 正是您所需要的。
(apply max '(1 2 3 4 5)) => (max 1 2 3 4 5) => 5
. - 顺便说一句,当您命名变量时,请检查该名称是否尚未被使用(例如 min、max , length, first, last)。在 REPL 中输入该名称并查看结果:
max => #<procedure:max>
。 Scheme 允许您在给定范围内更改该变量的值,但您将丢失以前的值。比较这两个函数:
(define (f1 xs first)
(first xs))
(define (f2 xs first-elem)
(first xs))
,这样称呼:
> (f1 '(1 2 3) 1)
> (f2 '(1 2 3) 1)
编辑:没有内置最小值和最大值的解决方案:
(define (find-extrema-help xs min-num max-num)
(if (null? xs)
(printf "The maximum of your list is ~a and the minimum is ~a." max-num min-num)
(find-extrema-help (cdr xs)
(if (< (car xs) min-num) (car xs) min-num)
(if (> (car xs) max-num) (car xs) max-num))))
(define (find-extrema xs)
(if (null? xs) "Empty list."
(find-extrema-help (cdr xs)
(car xs)
(car xs))))
查找极值子列表:
(define (drop xs number)
(cond ((null? xs) xs)
((= 0 number) xs)
(else (drop (cdr xs) (- number 1)))))
(define (take xs number)
(cond ((null? xs) '())
((= number 0) '())
(else (cons (car xs) (take (cdr xs) (- number 1))))))
(define (find-extrema-sublist xs down-index top-index)
(let ((len (- top-index down-index)))
(find-extrema (take (drop xs down-index)
len))))
您几乎从不需要“设置!”,并且您应该递归列表的结构,而不是它的长度。
对于非空列表,最大值为
car
,如果列表只有一个元素(即它的尾部是空列表),car
中的最大值和cdr
中的最大值,如果列表更长。
即
(define (max-element x y) (if (> x y) x y))
(define (max-list ls)
(if (null? (cdr ls))
(car ls)
(max-element (car ls) (max-list (cdr ls)))))
同样的原则也适用于最小值。
(define (min-element x y) (if (< x y) x y))
(define (min-list ls)
(if (null? (cdr ls))
(car ls)
(min-element (car ls) (min-list (cdr ls)))))
现在你需要两者,所以你应该制作一对(或其他一些结构)。
简单的方法是使用前面的两个函数,
(define (extrema ls) (cons (min-list ls) (max-list ls)))
但这很低效,因为它遍历了列表两次。
让我们做得更好。
这是同时应用于两个值的相同想法:
(define (extrema ls)
(if (null? (cdr ls))
(cons (car ls) (car ls))
(let ((cdr-extrema (extrema (cdr ls)))
(head (car ls)))
(cons (min-element head (car cdr-extrema))
(max-element head (cdr cdr-extrema)))))