在Racket中生成列表,其中包含日间结构列表

时间:2016-07-23 19:20:27

标签: list racket

我想写一个

的函数
  

1-消耗自然数(间隔)

     

2-生成一个计划,该计划是白天结构的列表   如下所示。

规则是,对于生成的每个列表,计划从(早上6点)开始,按给定间隔增加,并继续添加该间隔,直到它结束于(下午6点 - 即第18小时)并且不进行超过那个标记。 使用以下数据定义:

    (define-struct daytime (hours minutes))
    ;; A Daytime is a (make-daytime Nat Nat)
    ;; requires the number that represents hours to be 6<= hours <= 18
    ;; and requires the number that represents minutes to be < 60

我遇到的问题是如何创建具有白天结构的列表?我创建了一个列表,但它使用“list”而不是make-day。 该计划的一个例子应该是:

    (schedule 90) gives 
    (list (make-daytime 6 0) (make-daytime 7 30) (make-daytime 9 0)
          (make-daytime 10 30) (make-daytime 12 0) (make-daytime 13 30)
          (make-daytime 15 0) (make-daytime 16 30) (make-daytime 18 0))

1 个答案:

答案 0 :(得分:1)

你的意思是,定义一个能够返回该列表的函数吗?嗯,你想要的例子会给你n分钟的间隔。

有很多方法可以编写它,通常基于循环(递归或不循环)。如果要使用for循环,则需要一系列值来迭代。如果使用递归,则可以递增值,直到结束条件满足。您可以在for循环中增加一个值,但它使用变异,在函数式编程中被认为是一种不好的方法。让我告诉你两种方法的方法,并留下一些细节:)

此外,我将为循环运算符选择/ list,因为它可以很好地为我们返回一个列表。

for循环:正如我所说,我们需要迭代的值,所以我们可以使用序列函数来创建值。让我们使用(范围内)函数:

(sequence->list (in-range 0 (* 12 60) 90))

会给你分钟增量:

'(0 90 180 270 360 450 540 630)

完美,我们可以解决这个问题:

(define (schedule n)
  (for/list ([val (sequence->list (in-range 0 (* 12 60) n))])
    (let ([hour 0] ; <== calculate the hour part here
          [minute 0]) ; <== and minute here
      (make-daytime hour minute))))

现在,如果你想以递归的方式做同样的事情:

(define (schedule.v2 n)
  (define (schedule-aux result current-min)
    (cond
      [(>= current-min 720) result]
      [else
       (let ([hour 0] ; <== calculate the hour from current-min
             [minute 0] ; <== calculate the min from current-min
             [next-min (+ current-min n)])
         (schedule-aux
          (cons (make-daytime hour minute)
                result)
          next-min))]))
  (schedule-aux null 0))