Scheme 如何使用递归和迭代方法在SICP EX1.32中编写相同的累积函数
我一直在处理来自SICP的示例,在编写示例1.32中的两个版本的Accumate时遇到了一些问题。到目前为止,我的代码是这样的 递归版本:Scheme 如何使用递归和迭代方法在SICP EX1.32中编写相同的累积函数,scheme,racket,sicp,Scheme,Racket,Sicp,我一直在处理来自SICP的示例,在编写示例1.32中的两个版本的Accumate时遇到了一些问题。到目前为止,我的代码是这样的 递归版本: #lang racket (provide accumulate) (define (accumulate f a next b comb null) (if(> a b) null (comb (f a) (accumulate f (next a) next b comb null)
#lang racket
(provide accumulate)
(define (accumulate f a next b comb null)
(if(> a b)
null
(comb (f a)
(accumulate f (next a) next b comb null))))
#lang racket
(provide accumulate)
(define (accumulate f a next b comb null)
(define (iter cur_a result)
(if (> cur_a b)
result
(iter (next cur_a) (comb (f cur_a) result))))
(iter a null))
迭代版本:
#lang racket
(provide accumulate)
(define (accumulate f a next b comb null)
(if(> a b)
null
(comb (f a)
(accumulate f (next a) next b comb null))))
#lang racket
(provide accumulate)
(define (accumulate f a next b comb null)
(define (iter cur_a result)
(if (> cur_a b)
result
(iter (next cur_a) (comb (f cur_a) result))))
(iter a null))
虽然这两个函数对简单的comb
项(如加法和乘法)给出相同的结果,但类似`(lambda(xy)(+(*3x)(*3y)))的内容会导致这两个函数根据应用方向给出不同的结果。递归版本从范围的右端向左移动,而迭代版本从范围的左端向右移动
我想知道是否有可能改变函数的这个方向,这样就可以选择代码是向左运行还是向右运行。在我看来,要这样做,必须给出一个
prev
术语,而不是next
术语,这样函数才能以另一种方式运行。有没有其他方法可以在不涉及函数参数的情况下实现这一点?这是我的解决方案,来自我的sicp私有存储库
(define (term x) x)
(define (next i) (+ i 1))
;;; recursive process
(define (accumulate combiner null-value term a next b)
(if (> a b)
null-value
(combiner (term a)
(accumulate combiner null-value term (next a) next b))))
;;; iterative process
(define (accumulate-iter combiner null-value term a next b)
(define (iter a res)
(if (> a b)
res
(iter (next a) (combiner (term a) res))))
(iter a null-value))
(define (product term a next b)
(accumulate * 1 term a next b))
(define (product-iter term a next b)
(accumulate-iter * 1 term a next b))
(define (factorial n)
(product term 1 next n))
(define (factorial-iter n)
(product-iter term 1 next n))
(factorial 10)
(factorial-iter 10)
在第二个版本中,您没有使用
f
。什么是f
?很抱歉,在将cur_a与result组合时,我应该使用f。f是从当前a确定要组合的项的函数。请看,它可能相关。(续)它解决了相反方向的问题,但该技术也适用于此处。但是OP需要两个(累计(lambda(xy)(+(*3x)(*3y)))null(lambda(x)a下一个b)
和(累计iter(lambda(xy))(+(*3x)(*3y)))null(lambda(x)x)a next b)
给出相同的结果。@WillNess的确如此,但考虑到他没有粘贴足够的代码,只是简要地解释了他所做的事情,否则帮助他的努力会更大。从我的代码开始,他可以发现他做错了什么。