【SICP练习】25 练习1.31



练习1.31

题目中已经说的很清楚了,product用来返回在给定范围中各点的某个函数值的乘积。我们惊奇的发现这和前面的sum有着很大的相似,无非是将加法换成了乘法:

(define (product term a next b)

(if(> a b)

1

(* (term a)

(product term (next a) next b))))

既然在上一道习题中已经得出了sum的迭代版本,在这里同样也可以将它写成迭代的。

(define (product term a next b)

(define (product-iter a other)

(if (> a b)

other

(product-iter (next a)

(* (term a) other))))

(product-iter a 1))

不怕被笑话,我还去查了factorial的中文意思。有了product来写factorial不要太容易呀,只不过要借助以下很久之前用到过的lambda。不过完全也可以用额外定义的函数实现同样的功能,只不过在函数内用lambda会使代码更加简洁。

(define (factorial n)

(product (lambda (x) x) 1 (lambda (x) (+ x 1)) n))

下面我们来测试一下这个函数。

晕倒。。。博主轻飘飘的来了一个(factorial 50)结果返回了半个屏幕宽的数字。

话说我写到这里的时候才把a题做完,b题都没有看,没想到居然不知不觉中把b也碰巧做了。不过再看看原来a还没有写完,还要求pi的近似值。

那么这部分的策略是将分子和分母分开来看。先来看分子,我们可以准备一个函数,有一个参数n,如果n是1则返回2,n是奇数则加上1,n是偶数则加2。分母也可以用这种函数来产生。然后我们将左式中的4乘到右式,并且通过前面学的exact->inexact将分数转换成浮点数。最后我们就求出了pi。下面是完整的代码。

(define (get-pi n)

(define (get-numerator a)

(cond((= a 1) 2)

((odd? a) (+ a 1))

(else(+ a 2))))

(define (get-denominator b)

(cond ((odd? b) (+ b 2))

(else (+ b 1))))

(define (add1 c)

(+ c 1))

(* 4(exact->inexact 
(/ (productget-numerator 1 add1 n)

(product get-denominator 1 add1 n)))))

如是,我们再来检测检测。

(get-pi 300)

;Value: 3.1467982645089903

参数n越大,计算得到的pi越精确。

时间: 2024-10-11 12:26:36

【SICP练习】25 练习1.31的相关文章

SICP 1.25 1.26

解: 1.25 这么写的话a的n次方会很大,大数需要额外的处理.原始的expmod基于这个结论: (a*b)%c=((a%c)*(b%c))%c,证明如下: 设a=nc+k,b=mc+h,则 (a*b)%c=((nc+k)*(mc+h))%c=(nmc^2+nhc+mkc+kh)%c=(k*h)%c=((a%c)*(b%c))%c 1.26 这么写没有使计算量逐步减半. SICP 1.25 1.26,布布扣,bubuko.com

2016.3.25—2016.3.31这周的学习时间和内容

这周的学习内容:每周都在写感想,有时候感觉怪怪的,因为自己在之前从来没有在固定的时间内写感想,直到这学期开了刘砚老师的课以后,老师说每周写感想,对我们自己是有好处,最起码,我们在以后的知道自己在这学期学了什么,什么是有用的,什么是对自己加深知识的东西,等等,非常感想老师,在期末我可以了解,可以打开博客回忆回忆自己这个学期的收获.每周上课都是三个小时,在课堂上基本都是在编代码,想问题,在这周课堂上,老师让我们结对编程,就是说让俩个人一组编程序,我和王瑞分到一组,这个是随机分的,所有也不会存在侥幸心

继承派生产生的切割问题

1 #include <iostream> 2 #include <string> 3 using namespace std; 4 class people 5 { 6 public: 7 string name; 8 int age; 9 virtual void print(); 10 }; 11 12 class teacher:public people 13 { 14 public: 15 int wage; 16 virtual void print(); 17 18

199. Binary Tree Right Side View

题目: Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. For example:Given the following binary tree, 1 <--- / 2 3 <--- \ 5 4 <--- You should return [1, 3,

三.主从DNS 与DNS相关配置

####三.主从DNS DNS加密####1.主从DNS的配置1)配置好两台DNS服务器2)其中从DNS服务器配置如下:vim /etc/named.rfc1912.zones--------------------------------------- 25 zone "westos.com" IN { 26         type slave; 27         masters { 172.25.254.100; }; 28         file "slaves

CodeForces 716B Complete the Word

留坑! 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=50000+2; 4 char ca[N]; 5 int main() 6 { 7 int i,j; 8 9 while(scanf("%s",ca)!=EOF) 10 { 11 12 if(strlen(ca)<26) 13 { 14 printf("-1\n"); 15 continue; 16 } 17 int

哈夫曼树与哈夫曼编码

哈夫曼树与哈夫曼编码 术语: i)路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径. 路径中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. ii)结点的权及带权路径长度 若对树中的每个结点赋给一个有着某种含义的数值,则这个数值称为该结点的权. 结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积. iii)树的带权路径长度 树的带权路径长度:所有叶子结点的带权路径长度之和,记为WPL. 先了解一下

原创:goldengate从11.2升级到12.1.2

goldengate从11.2升级到12.1.2 1.停止抽取进程 GGSCI (001.oracle.drs.dc.com) 286> stop EXTSJ01 2. 停止投递和复制进程 等待投递进程传输完和复制进程加载完毕.当投递进程的Write Checkpoint #1的Sequence和RBA和复制进程的 Current CHECKPOINT的Sequence和RBA相同时表示已同步完毕 2.1检查投递进程: GGSCI (001.oracle.drs.dc.com) 202> in

Scala 具体的并行集合库【翻译】

原文地址 本文内容 并行数组(Parallel Array) 并行向量(Parallel Vector) 并行范围(Parallel Range) 并行哈希表(Parallel Hash Tables) 并行散列 Tries(Parallel Hash Tries) 并行并发 Tries(Parallel Concurrent Tries) 参考资料 并行数组(Parallel Array) 一个 ParArray 序列包含线性.连续的元素数组.这意味着,通过修改底层数组,可以高效地访问和修改元