【问题标题】:Transpose a matrix in racket (list of lists在球拍中转置矩阵(列表列表
【发布时间】:2015-08-26 19:24:31
【问题描述】:

我在球拍中有一个列表列表,必须转置它们。

(: transpose ((list-of(list-of %a)) -> (list-of (list-of %a))))

(check-expect (transpose (list (list 1 2 3)
                               (list 4 5 6)))
              (list (list 1 4)
                    (list 2 5)
                    (list 3 6)))

(define transpose
  (lambda (xs)
    (cond
      ((empty? xs)empty)
      ((pair? xs)(make-pair  (make-pair (first(first xs))  (make-pair (first(first(rest xs)))empty)) (transpose (rest(rest xs))))))))

这是我目前的代码。 我认为问题出在递归调用中(如果我错了,请纠正我)。

实际结果是(list (list 1 4))。其余的似乎有点被忽略了。

如果有人知道问题或有提示,那真的会帮助我。

【问题讨论】:

    标签: list matrix scheme racket transpose


    【解决方案1】:
    (define (transpose xss)
      (apply map list xss))
    

    如果您像我一样是 Scheme 的新手,您会想知道 apply map list 技巧是如何工作的。 这一切都归结为了解applymap

    首先,apply 完成了它的工作。它需要一个函数、一些固定参数和一个参数列表。 它使用固定参数调用函数,后跟扁平列表参数。 所以:

    (apply map list '((1 2) (3 4)))
                    ^^^^^^^^^^^^^^-- list of arguments
               ^^^^ ---------------- a fixed argument
           ^^^ --------------------- function
    

    评估为:

    (map list '(1 2) '(3 4))
    

    注意列表列表是如何变成两个列表的。

    现在map 接受一个 N 参数函数和 N 个等长列表。然后它返回一个列表,其中每个元素都是函数的一个应用程序。 例如

    (map + '(1 2) '(3 4))
    

    评估为:

    (list (+ 1 3) (+ 2 4))
    

    在转置技巧中,函数只是list,所以:

    (map list '(1 2) '(3 4))
    

    评估为:

    (list (list 1 3) (list 2 4))
    

    第一个list 构造一个列表,因为map 总是返回一个列表,而另外两个是对传递的list 函数的调用。

    【讨论】:

      【解决方案2】:
      (define (tr ls)
        (if (empty? (car ls)) empty
       (if (null? ls) empty
           (cons (map car ls) (tr (map cdr ls))))))
      

      【讨论】:

      • 您可以通过缩进 4 个空格将代码放入代码块中。还请添加您的答案的解释,而不仅仅是一段代码。
      • 请通过在您的纯代码答案中添加解释来帮助消除 StackOverflow 是免费代码编写服务的误解。
      • 问题来自 2015 年
      【解决方案3】:

      for/list 可以按顺序使用来创建带有转置项的列表列表:

      (define (transpose_ lol)                    ; lol is list of lists
        (for/list ((i (length (list-ref lol 0)))) ; loop for length of first inner list
          (for/list ((il lol))                    ; for each inner list (il)
            (list-ref il i))))                    ; get its item
      

      测试:

      (transpose_ (list (list 1 2 3)
                        (list 4 5 6)))
      

      输出:

      '((1 4) (2 5) (3 6))
      

      【讨论】:

        【解决方案4】:

        transpose的最简单定义是:

        (define (transpose xss)
          (apply map list xss))
        

        为什么会起作用?

          (apply map list '((a b) (d e))
        = (apply map List '((a b) (d e))    ; use List rather than list
        = (map List '(a b) '(d e))
        = (list (List 'a 'd) (List 'b e))
        = '((a d) (b e))
        

        这里List 用大写字母拼写只是为了显示哪个list 是用户给出的,哪个是map 生成的。

        这是一个不太“聪明”的解决方案。它使用第一列 一个矩阵成为转置矩阵的第一行。

        (define transpose
          (lambda (xss)
            (cond
              [(empty? xss)         empty]
              [(empty? (first xss)) empty]
              [else                 (define first-column   (map first xss))
                                    (define other-columns  (map rest  xss))
                                    (cons first-column
                                          (transpose other-columns))])))
        

        【讨论】:

        • Python 中的等价物是apply(zip, [['a', 'b'], ['c', 'd'], ['e', 'f']])。我知道您没有询问 Python,但我将其作为一般知识提供。 Python 有很多以“垃圾场战争”风格结合在一起的 lispy 位。它也比任何真正的 lisp 更容易与朋友分享。
        • 在 20/21 冬季为我所有的 Informatik 1 学生提供服务。请注意,我们已将上述代码添加到我们的抄袭检查器中。不要复制外国代码——尝试自己解决问题。谢谢!问候,-TG
        猜你喜欢
        • 1970-01-01
        • 2019-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多