定义一个计算方形函数,用于计算方阵的轨迹

时间:2017-04-24 18:48:29

标签: scheme lisp

  

实施例

     

(trace '((1 2 3) (4 5 6) (7 8 9)))应评估为15(1 + 5 + 9)。   提示:使用map获取可以递归应用跟踪的较小矩阵。矩阵应该是平方的。

我试图这样做,但我似乎无法做到这一点,我试图首先获得对角线。

define (diagonals m n)

(append

(for/list ([slice (in-range 1 (- (* 2 n) 2))])
 (let ((z (if (< slice n) 0 (add1 (- slice n)))))
   (for/list ([j (in-range z (add1 (- slice z)))])
     (vector-ref (vector-ref m (sub1 (- n j))) (- slice j))))

有没有办法使用map以非常简单的递归方式解决这个问题。

我试着像那样解决它。

define (nth n l)
(if (or (> n (length l)) (< n 0))
(if (eq? n 0) (car l)
(nth (- n 1) (cdr l)))))

(+ (nth 3 '(3 4 5)) (nth 2 '(3 4 5)) (nth 3 '(3 4 5)))

但它也没有用。

2 个答案:

答案 0 :(得分:1)

虽然我不认为回答家庭作业问题总的来说是一个好主意,但我无法抗拒,因为它是Lisp程序如此美丽以及可能如此可怕的例子。

真是太美了:

  • 递归算法几乎与感应的数学证明相同,而且它非常漂亮和聪明;

有多可怕:

  • 矩阵不是语义嵌套列表,只是这个可怕的双关语假装它们(我不确定我使用first&amp; rest是否会使它更好或更差);
  • 它根本没有任何理由就像疯了一样;
  • 我很确定它的时间复杂度是n ^ 2,可能是n。

当然,Lisp程序不一定非常糟糕。

计算矩阵的轨迹:

  • 如果矩阵为空,则跟踪为0;
  • 否则,通过删除第一行和第一行,将左上角的元素添加到矩阵的轨迹中。

或者:

(define (awful-trace m)
  (if (null? m)
      ;; the trace of the null matrix is 0
      0
      ;; otherwise the trace is the top left element added to ...
      (+ (first (first m))
         ;; the trace of the matrix without its first row and column which
         ;; we get by mapping rest over the rest of the matrix
         (awful-trace (map rest (rest m))))))

你可能会想到以下功能更好,但它在上述所有方面都同样糟糕,而对于那些不熟悉辅助尾递归功能的人来说,更难以阅读累积器技巧:

(define (awful-trace/not-actually-better m)
  (define (awful-loop mm tr)
    (if (null? mm)
        tr
        (awful-loop (map rest (rest mm))
                    (+ tr (first (first mm))))))
  (awful-loop m 0))

答案 1 :(得分:0)

尝试:

(apply + (map (lambda (index row) (list-ref row index))
             '(0 1 2)
             '((1 2 3) (4 5 6) (7 8 9))))

当然,把它变成一个函数。

要处理大于3x3的矩阵,我们需要更多的索引。

由于map在遍历最短的列表时停止,(0 1 2)列表可以手工填充,就像......你对你认为最大的矩阵的最佳猜测在你毕业之前,我会用Scheme中的嵌套列表来表示,再也不会看到这些东西了。