Matrix 函数规划中的有效矩阵

Matrix 函数规划中的有效矩阵,matrix,scheme,racket,sicp,Matrix,Scheme,Racket,Sicp,我是C/C++程序员,我开始学习Racket/阅读SICP。我有一个关于函数编程中矩阵的有效表示的问题 函数式编程中矩阵的最有效表示是什么?旧的好数组?我这样问是因为SICP作者使用矩阵列表 这是一个现实世界的问题:在我们的生产代码中,我们有一个函数,它在每一步上为矩阵单元设置随机值。简化的代码如下所示: //最多N个随机单元,用随机值初始化 //矩阵是游戏场的当前状态 for(n=0;n

我是C/C++程序员,我开始学习Racket/阅读SICP。我有一个关于函数编程中矩阵的有效表示的问题

  • 函数式编程中矩阵的最有效表示是什么?旧的好数组?我这样问是因为SICP作者使用矩阵列表
  • 这是一个现实世界的问题:在我们的生产代码中,我们有一个函数,它在每一步上为矩阵单元设置随机值。简化的代码如下所示:
  • //最多N个随机单元,用随机值初始化

    //矩阵是游戏场的当前状态

    for(n=0;n
    此代码简单有效。对于一个大的不可变矩阵,如何以函数式的方式有效地编写此代码?可能吗?如果是的话,怎么办


    非常感谢您的回答

    正如奥斯卡所说,最传统的函数式编程方法是使用链表。然而,一种更直接的方法(尽管有一些变异)是使用载体

    然而,既然你们提到你们在拍中做这个,你们实际上可以用它来制作你们的矩阵。您可以使用向量的向量,如中所示:

    (define my-matrix
      (for/vector ([i (in-range 3)])
        (for/vector ([j (in-range 3)])
          (random))))
    
    这是一个3x3的随机数向量。现在您可以使用两次从中获取元素

    ;; Evaluates to the middle most cell in the matrix
    (vector-ref (vector-ref my-matrix 1) 1)
    
    另一种方法是采用类似C的方法,对整个矩阵使用单个向量。当然,这需要为宽度存储一个额外的参数,但可以让事情变得更清晰。1例如,可以创建一个包含数字1到9的3x3矩阵:

    (define matrix-width 3)
    (define matrix
      (for/vector ([i (in-range 1 10)])
        i))
    
    现在只需要一个
    向量ref
    就可以得到元素:

    ;; This also gets the middle most cell.
    (vector-ref matrix (+ 1 (* 1 matrix-width)) ; => 5
    
    当然,如果您想经常这样做,可以将其包装到单个数据结构中:

    (struct matrix (width data))
    (define (make-matrix width height)
      (make-vector (* width height)))
    (define (matrix-ref m i j)
      (vector-ref (matrix-data m) (+ i (* j (matrix-width m)))))
    (define (matrix-set! m i j v)
       (vector-set! (matrix-data m) (+ i (* j (matrix-width m))) v))
    
    当然,您可以做得更进一步,只需多做一点工作和一个小宏,您甚至可以添加
    for/matrix
    in matrix
    作为循环构造,以及矩阵数学库。但是在某一点上,你将有效地创建带有打字球拍的库

    1当然,这纯粹是主观的,也取决于您的课程


    2从技术上讲,它也适用于标准、非类型、敲打,但速度要慢得多。

    SICP的作者希望教授计算机科学,特别是函数式编程。人们的兴趣不在于在GNU/MIT Scheme解释器中显示不同的工具。40年来,我一直把SICP作为灵感来源。
    你应该使用向量

    谢谢你的回答。我同意命令式方法,我只是好奇如何用函数的方式解决问题。也许我可以问问哈斯克尔的人,他们生活在一个不变的世界里:)
    (struct matrix (width data))
    (define (make-matrix width height)
      (make-vector (* width height)))
    (define (matrix-ref m i j)
      (vector-ref (matrix-data m) (+ i (* j (matrix-width m)))))
    (define (matrix-set! m i j v)
       (vector-set! (matrix-data m) (+ i (* j (matrix-width m))) v))