在球拍

时间:2017-12-06 02:27:51

标签: racket

您好,

我正在研究一些球拍练习。我知道Racket有一个内置的min函数,但我试图从头开始编写一个。我做了一些工作并在网上找到了一些想法,但代码效率不高。我想我需要使用辅助方法。关于如何进一步修改此代码以使其高效,我有点迷失。我在显示的测试用例上运行了这段代码并且花了太长时间。在较小的测试用例中,代码确实返回正确的结果。任何建议都会很棒。

(define (minim lst)
    (cond 
      ((null? (cdr lst)) (car lst))
      ((< (car lst) (minim (cdr lst))) (car lst))
      (else 
        (minim (cdr lst)))) )

(minim&#39;(3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4))

会返回1.

2 个答案:

答案 0 :(得分:3)

假设列表未排序,找到最小值的最自然方式是遍历整个列表,将每个元素与某个初始最小值进行比较,每当元素小于该最小值时,元素将保存为新的最小最后,当列表变空时返回min(基本情况)。

例如,请考虑以下事项:

(define (minimum lst acc)
  (cond
    ((null? lst) acc)
    ((< (car lst) acc)
     (minimum (cdr lst) (car lst)))
    (else
     (minimum (cdr lst) acc))))

(define (mymin lst)
  (if (null? lst)
      #f
      (minimum (cdr lst) (car lst))))

mymin需要O(n)时间在列表中查找最小值,使用n-1比较,其中n是列表中元素的数量。

您可以在本地使用更长和更短的列表进行测试:

(mymin   '(3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4
           3 4 2 9 3 8 7 7 7 7 7 7 7 7 7 8 2 1 3 2 2 2 3 4 -1))
=> -1

答案 1 :(得分:1)

代码运行的时间比需要的时间长,因为对于列表中的每个项目,minim在测试条件下以cdr递归调用。它有所谓的tree recursion

编写minim的更多“Rackety”方法可能是定义一个比较两个数字的简单函数:

(define (min-of-2 x y)
  (if (< x y)
      x
      y))

然后使用foldl

在列表中弃用
(define (minim lst)
  (foldl min-of-2 (first lst) (rest lst)))

使用foldl的时间是指列表上的操作根据列表内容生成单个值,如此处所示。

函数min-of-2不需要命名,可以作为lamda传递。例如:

(define (minim lst)
  (foldl 
    (lambda (x y) (if (< x y) x y))
    (first lst)
    (rest lst)))