正如源文件名称(ex1.12.scm)所建议的那样,我刚刚开始通过阅读SICP来学习麻省理工学院的方案。在练习1.12中,我被要求“通过递归过程计算Pascal三角形的元素”。为了好玩和额外的练习,我写了一个程序打印整个三角形。(我花了几分钟打印一个帕斯卡三角形,花了几个小时美化它:/)
(define (pascal x)
(define (pascal-iter m n max-len)
(cond ((and (> m 0) (> n 0))
(pascal-iter m (- n 1) max-len)
(beauti-print (pascal-item m n) max-len))
((= n 0) (pascal-iter (- m 1) (- m 1) max-len)
(display "\n")
(print-space (* (- x m) max-len)))
((= m 0) "Done")))
(define (pascal-item m n)
(cond ((= n 1) 1)
((= n m) 1)
(else (+ (pascal-item (- m 1) (- n 1))
(pascal-item (- m 1) n)))))
(define (beauti-print item max-len)
(print-space (floor (- max-len
(/ (num-of-digit item) 2))))
(display item)
(print-space (ceiling (- max-len
(/ (num-of-digit item) 2)))))
(define (num-of-digit n)
(+ (floor (/ (log n) (log 10))) 1) )
;; (print-space 1) -> " "
;; (print-space 1.5) -> " "
(define (print-space n)
(cond ((> n 0) (display " ")
(print-space (- n 1)))
(else (display ""))))
(pascal-iter x x (num-of-digit (pascal-item x (/ x 2)))))
(pascal 12)这是输出:
;Loading "ex1.12.scm"...
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
;... done它的一个缺点是显而易见的:递归非常昂贵。事实上,(pascal 15)会在我的机器上生产;Aborting!: maximum recursion depth exceeded。
但是,在回答这个问题时,请不要过于强调性能相关的问题,因为我认为,就目前而言,好的编程习惯的形式比优化算法更重要。因此,请关注可读性、代码样式等。
发布于 2016-11-21 05:59:08
一个对设计好的软件至关重要的设计原则是“分离关注点”。换句话说,每个功能都应该关注做一件事,而且只做一件事。
如果您后退一步,查看一下pascal函数,您将看到它正在尝试同时执行两项任务:
你可以把这些顾虑分开。
让我们从pascal函数开始。它应该只计算三角形中的值。它应该返回一个“行”列表,其中一行表示一个数字列表。
所以我们可以使用pascal来计算一个数字列表。现在我们想把这张清单打印出来。我们可以在一个函数中完成这一切(这没有什么问题)。但是如果我们小心的话,我们可以使事情变得更通用(从而可重用)。我们可以组成漂亮的打印三角形如下:
我们可以定义函数format-row、center-lines和print-lines来处理这些任务。现在我们可以定义一个函数pretty-print-pascal,它将这些函数组合在一起:
(define pretty-print-pascal (x)
(print-lines (center-lines (map format-row (pascal x)))))发布于 2016-11-21 03:15:24
pascal-item的次级定义是在1.12练习中所要求的。但是,它完全不适合计算X行的整个三角形。没有适当的数据结构(列表、向量、哈希表.)可怜的pascal-item必须做所有的工作(而缺少记忆必须比实际需要的还要多很多次)
没有数据结构也迫使您将打印逻辑与三角形的一步一步的计算混为一谈,这虽然聪明,但它有点难以理解,而且很难单独使用。
我的建议是在书中继续前进,到那时,这一切将变得更加清晰。
https://codereview.stackexchange.com/questions/147418
复制相似问题