定义一个计算方阵轨迹的scheme函数
范例定义一个计算方阵轨迹的scheme函数,scheme,lisp,Scheme,Lisp,范例 (trace'((1234)(456)(789))应计算为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 (
(trace'((1234)(456)(789))
应计算为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))))
(+(第n个3'(3 4 5))(第n个2'(3 4 5))(第n个3'(3 4 5)))
虽然我不认为回答家庭作业的问题是一个好主意,但我无法抗拒,因为这是一个例子,既展示了Lisp程序的美妙之处,也展示了Lisp程序的可怕之处 什么是如此美丽:
- 递归算法几乎等同于归纳法的数学证明,它非常漂亮和聪明李>
- 矩阵不是语义上嵌套的列表,假装它们是一个可怕的双关语(我不确定我使用
和first
是更好还是更糟)李>rest
- 它就像疯了一样毫无理由李>
- 我很确定它的时间复杂度是n^2,而它可能是n
- 如果矩阵为空,则跟踪为0李>
- 否则,通过删除第一行和第一列,将左上角的元素添加到矩阵的跟踪中
(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))
尝试:
当然,把它变成一个函数
要处理大于3x3的矩阵,我们需要更多的索引
由于
map
在遍历最短的列表时停止,因此(0 1 2)
列表可以手动填充到最大值。。。在毕业之前,您最好猜测Scheme中嵌套列表所代表的最大矩阵,以后再也看不到这些内容。请将代码从注释移动到问题,并正确设置格式。使用“编辑”按钮。好的,我会的,谢谢。现在请修复parens和indentation并删除不必要的注释(我将删除我的注释)。你看,我不是lisp方面的专业人士,因此不擅长indentationEmacs可以按我们期望的方式为你缩进代码:-)lisp中的列表是线性访问,因此到达对角线只能是二次访问。这就是说,map
重新构建顶级cons结构,从而获得二次空间行为;您可以为第n行应用cdr
n次,以获得恒定的空间(当然时间仍然是二次的)。为第n行调用cdr
n次也无济于事,这不是因为Lisp“糟糕”,而是因为使用了数据结构你的累积代码仍然调用map;它所能做到的就是避免O(n)深度叠加——与二次空间和时间相比,这并不重要。我在抽什么?!当然可以使用第n个而不是第n个cdr。我认为它仍然是线性的,所以总体上是二次的OTOH OP使用的是向量ref
,所以它们的矩阵可能是向量列表?这将改变一切。@WillNess:是的,它是二次的,正如你所说的,计算这样一个结构的轨迹的任何东西都不能比这更好(即使是OP将它变成向量的技术,因为这样做本身就是二次的)。累加器版本在空间上是线性的,比如GC或等价物:在成为垃圾之前,它一次不需要超过n个新的conse。我显然不认为Lisp很糟糕:我认为一些程序(用Lisp和其他语言)很糟糕,包括这一个。在“糟糕”的引语后面有一个隐含的微笑。应该说得很清楚至于累积版本的空间线性:你是对的。我在考虑新消费的数量,所以这是一个时间复杂的事情。当然,一个足够聪明的编译器只需维护一堆指向原始结构的指针,根本不需要考虑。从这个角度来看,(第一个)代码变成了一个高级描述,而且很漂亮,imho.)
(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))
(apply + (map (lambda (index row) (list-ref row index))
'(0 1 2)
'((1 2 3) (4 5 6) (7 8 9))))