【问题标题】:Racket Data Processing Issue: Vector Pointer is Void球拍数据处理问题:矢量指针无效
【发布时间】:2016-08-19 16:10:57
【问题描述】:

问题

我有一个任务要编写一个球拍函数:

取一个出发地、一个目的地(均为 3 个字符的机场代码), 和航班数据列表并返回延迟统计列表 对于从始发地到目的地的所有航班,有一个缺点 cell (origin.destination) 作为第一个元素。

数据必须格式化为六个比例,即至少晚点 1、15、30、60、120 和 180 分钟的航班比例。

在下面的代码中,我编写了一个尾部优先递归函数,每次找到匹配的飞行数据时,它都会在长度为 6 的向量中增加一个值。然后,一旦递归检查了数据列表,就会返回一个比例列表。

我收到以下错误,表明达到增量代码时part 无效。 part 不应该在整个函数中指向生成的向量吗?

错误

vector-ref: contract violation
  expected: vector?
  given: #<void>
  argument position: 1st
  other arguments...:    3

代码

(require "ontime.rkt")

(define (ontime-stats-by-route orig dest data)
  (define (aux orig dest data part)
    (if (null? data)
        (let ([sum (foldl + 0 (vector->list part))])
          (list (cons orig dest)
                (/ (vector-ref part 0) sum)
                (/ (vector-ref part 1) sum)
                (/ (vector-ref part 2) sum)
                (/ (vector-ref part 3) sum)
                (/ (vector-ref part 4) sum)
                (/ (vector-ref part 5) sum)))
        (if (and
             (eq? orig (car (car (cdr (car data)))))
             (eq? dest (car (cdr (car (cdr (car data)))))))
            (let ([late (car (cdr (cdr (cdr (car data)))))])
              (cond
                [(>= late 180) (aux orig dest (cdr data)
                                    (vector-set! part 5 (vector-ref part 5)))]
                [(>= late 120) (aux orig dest (cdr data)
                                    (vector-set! part 4 (vector-ref part 4)))]
                [(>= late 60) (aux orig dest (cdr data)
                                   (vector-set! part 3 (vector-ref part 3)))]
                [(>= late 30) (aux orig dest (cdr data)
                                   (vector-set! part 2 (vector-ref part 2)))]
                [(>= late 15) (aux orig dest (cdr data)
                                   (vector-set! part 1 (vector-ref part 1)))]
                [(>= late 1) (aux orig dest (cdr data)
                                  (vector-set! part 0 (vector-ref part 0)))]
                [else (aux orig dest (cdr data) part)]))
            (aux orig dest (cdr data) part))))
  (let ([count (make-vector 6 0)])
    (aux orig dest data count)))

(ontime-stats-by-route "BWI" "BDL" ontime)

【问题讨论】:

  • 在球拍中#&lt;void&gt; 不是空指针,通常不以任何方式用于可空值。它通常来自不返回任何有用值的过程,通常是因为它们有副作用。

标签: vector functional-programming racket tail-recursion


【解决方案1】:

问题在于,vector-set!set-box! 等突变函数返回 #&lt;void&gt;,因为它们用于它们的突变,而不是它们的返回值。这很好,因为它鼓励在明确的功能代码(您可以根据需要操作和重新排序)和明确的命令代码(您必须更加小心)之间进行一些分离。这也是这些函数通常以! 结尾的原因。

因此,与其将(vector-set! part ....) 作为新的part 参数传递,您应该单独进行此突变,然后将part 本身作为参数传递,因为它现在已突变:

          (cond
            [(>= late 180)
             (vector-set! part 5 (vector-ref part 5))
             (aux orig dest (cdr data) part)]
            [(>= late 120)
             (vector-set! part 4 (vector-ref part 4))
             (aux orig dest (cdr data) part)]
            [(>= late 60)
             (vector-set! part 3 (vector-ref part 3))
             (aux orig dest (cdr data) part)]
            [(>= late 30)
             (vector-set! part 2 (vector-ref part 2))
             (aux orig dest (cdr data) part)]
            [(>= late 15)
             (vector-set! part 1 (vector-ref part 1))
             (aux orig dest (cdr data) part)]
            [(>= late 1)
             (vector-set! part 0 (vector-ref part 0))
             (aux orig dest (cdr data) part)]
            [else
             (aux orig dest (cdr data) part)])

不过,像(vector-set! part 5 (vector-ref part 5)) 这样的东西根本不会改变索引5 的值。你的意思是(vector-set! part 5 (add1 (vector-ref part 5))),因为你说你想增加值?

          (cond
            [(>= late 180)
             (vector-set! part 5 (add1 (vector-ref part 5)))
             (aux orig dest (cdr data) part)]
            [(>= late 120)
             (vector-set! part 4 (add1 (vector-ref part 4)))
             (aux orig dest (cdr data) part)]
            [(>= late 60)
             (vector-set! part 3 (add1 (vector-ref part 3)))
             (aux orig dest (cdr data) part)]
            [(>= late 30)
             (vector-set! part 2 (add1 (vector-ref part 2)))
             (aux orig dest (cdr data) part)]
            [(>= late 15)
             (vector-set! part 1 (add1 (vector-ref part 1)))
             (aux orig dest (cdr data) part)]
            [(>= late 1)
             (vector-set! part 0 (add1 (vector-ref part 0)))
             (aux orig dest (cdr data) part)]
            [else
             (aux orig dest (cdr data) part)])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多