- 博客(102)
- 收藏
- 关注
原创 sicp每日一题[2.85-2.86]
从 2.83 开始我感觉做的有点怪怪的,我似乎没有很好地理解这些题目的目的,也没有在写完之后用测试样例监测,只是简单的实现了那个逻辑。所以做到练习 2.85 我已经不知道在干什么了,所以我决定重新写一遍,把实数这一层也加上,同时每道题目新增的过程都要有对应的测试样例。结果写了两天也没写出来,参考别人的修改也不成功,除非完全用别人的代码,我心态崩了。继续死磕下去,可能这个每日一题就要彻底放弃了,所以这两道题我决定先拿别人的代码贴上,然后往下学,如果后面有机会再回过头来改我自己的代码。。
2024-11-23 14:06:57
934
原创 sicp每日一题[2.83]
这道题挺简单的,只要在每个包里用下一级的构造方法生成符合下一级规则的数就行。因为有理数本身就可以直接看成实数,所以我没有写有理数到实数和实数到复数的转换过程,这样直接在 2.81 的基础上修改就行了。
2024-11-20 08:09:53
239
原创 sicp每日一题[2.82]
这道题还是挺难的,题目的提示是通过一个双循环来依次进行类型转换,我参考别人的代码修改了很久最后才能跑通,用下面的代码替换上一题的 apply-generic 过程,可以验证是否能用。
2024-11-19 08:59:03
213
原创 sicp每日一题[2.81]
a. 我在 2.80 和本节的新 apply-generic 的基础上添加了本题所需的代码,然后生成了2个复数 3+4i 和 5+12i,第一次直接运行程序陷入了无穷递归调用,所以我添加了 trace 函数追踪 apply-generic 的调用情况。b. 很显然 Louis 的代码对于2个参数是相同类型时的情况是不正确的,不仅没有解决相同类型参数的问题,反而使得问题更严重了。c. 要解决死循环的问题,只要在判断 t1->t2 之前先判断 t1 和 t2 是否是相同类型,如果类型相同就不进行强制类型转换。
2024-11-18 08:38:36
860
原创 sicp每日一题[2.79]
这道题也挺简单的,分别在一般数字、有理数和复数包里实现这个函数就行了,以下代码复数部分在 2.77 的基础上添加,一般数字和有理数在书上 2.5.1 的基础上添加。看了一下别人的答案,有理数部分可以通过十字相乘来使得答案更简单。
2024-11-16 13:23:04
193
原创 sicp每日一题[2.78]
这道题难度不大,就是说我们在设计程序的时候,先用内置的 number?函数来判断,如果确实是数字,那就不用添加 scheme-number 标签,否则还跟之前一样。
2024-11-15 19:24:16
611
原创 sicp每日一题[2.77]
为了看得更清楚,这里用 magnitude-rectangular 表示 install-rectangular-package 包中的 magnitude 过程。可以看出,在上面的过程中,一共调用了2次 apply-generic,第一次它根据 complex 和 magnitude 去寻找 install-complex-package 包中对应的过程;这里要注意2点,一个是要安装这几个包,另一个是在安装这些包之前需要加上。
2024-11-14 19:37:26
666
原创 sicp每日一题[2.76]
无论是添加操作还是类型,都比较简单。对于 message-passing 风格,它使用一个动态的函数作为分发的依据,要添加新的类型,只需要为新类型添加一个分发函数;但是要添加新的操作,就需要在每个类型的分发函数中,添加一个新的分支,原有类型越多,添加新操作修改的地方就越多。对于 explicit dispatch 风格,每添加一种新类型,都需要编写新类型自身的操作函数,并在每个通用操作函数的 cond 中,添加一个新的分支;而添加新的操作,除了编写新的通用操作函数,还需要为每个类型添加类型相关的操作函数。
2024-11-13 19:29:44
330
原创 sicp每日一题[2.74]
a. 这道题里,部门名称就相当于前面所说的类型,获取部门信息就是操作,我们根据这两个信息从提前建好的二维表里提取雇员所属部门的文件。每个部门文件都应该有一个 get-division 的过程,它根据雇员姓名获取对应的部门文件。d. 每次接管一个新公司,都要把上述提到的过程添加到二维表里,使用的时候根据部门类型和操作来获取对应公司的过程。b. 这道题跟上一题很像,只是这次是从某个雇员的记录中获取工资信息。c. 这道题就是依次检查所有部门,根据雇员名称获取记录。
2024-11-11 19:43:15
843
原创 sicp每日一题[2.72]
这道题如果只考虑 2.71 的那种情况,最常用的符号永远只需要1位,时间复杂度是 O(1), 最不常用的符号根据 2.71 的图可以看出来,每增加一个符号,所增加的步骤只是常数个,所以时间复杂度应该是 O(n)。
2024-11-07 18:43:09
339
原创 sicp每日一题[2.71]
这道题挺简单的,只要明白了霍夫曼编码的逻辑,自己画一下就可以了,这会是一种非常不平衡的树,除了权重最低的两个符号构成了一个完整的子树,其他的子树都只有一个叶子,n=5 时如下图所示,n=10太多了就不画了,跟这个类似。可以看出,当有 n 个符号时,使用频率最高的符号只需要1位就可以表示,频率最低的则需要 n-1 位。
2024-11-06 22:02:58
349
原创 sicp每日一题[2.70]
这一步就会跳出,我尝试了好几个方法也没找到怎么解决,最后直接把歌词改成全大写了。解决了大小写问题,我又遇到了相同的提示,一步步调试之后终于发现了问题,我练习 2.68 的 encode-symbol 本身就有问题,改完之后终于成功了。这道题本来应该是非常简单的,只需要调用 2.68 和 2.69 的函数就行,但是我却遇到了好几个麻烦,第一个是大小写问题,我在生成霍夫曼树的时候,用的都是题目中默认的大写字母,但是要翻译的歌词却是既有大写又有小写,所以在 encode-symbol 函数的。
2024-11-05 20:36:54
242
原创 sicp每日一题[2.69]
这道题虽然题目说不会很复杂,但是我觉得还是挺难的。首先是要理解 successive-merge 的作用,它是要把一个个叶子按照权重由小到大依次合并成一个树,由于参数已经用 make-leaf-set 进行了排序,所以我们只要从前往后依次把这些“叶子”合并起来就行,每次合并好的树作为一个新的“叶子”与其他叶子一起进行新的合并;
2024-11-04 19:55:29
295
原创 sicp每日一题[2.67-2.68]
这道题对我来说难度挺大的,我一开始就被如果符号就是树的根怎么表示难住了,因为书上讲的好像都是左边是0,右边是1,却没有关于根上字符的表示,我也没有想到可以直接用“空”表示。最后看了别人的答案才终于明白了。
2024-11-03 08:58:34
707
原创 sicp每日一题[2.66]
这道题还是挺简单的,由于是有序的二叉树,所以可以先比较根与要查找的数字的大小,如果相等就查到了;如果根小于要查找的数,则递归调用判断右子树中是否包含这个数;如果根大于要查找的数,则去左子树去查即可。
2024-11-02 11:30:43
230
原创 sicp每日一题[2.65]
这道题难度还是挺大的,一开始我不知道怎么直接对2颗树求交集和并集,而且要在 O(n) 的时间复杂度内。上网看了一下别人的答案,发现他们都是先用 2.63 的 tree->list-2 把树转为列表,然后再求交集并集,最后再用 2.64 的 list->tree 把结果转成树结构。这样我就明白怎么做了,尤其是求并集可以直接参考 2.62 的答案,但是稍作修改,让它能去除重复元素,求交集虽然没有现成的,但是参考并集的方法也不难。
2024-11-01 08:42:09
439
原创 sicp每日一题[2.63-2.64]
b. 对于 tree->list-1,因为 append 需要花费线性时间,所以T(n) = 2 * T(n/2) + O(n/2),时间复杂度为 O(n * log n);对于 tree->list-2,T(n) = 2*T(n/2) + O(1),时间复杂度为 O(n),第二个增长的慢一些。所以 T(n) = 2T(n/2) + O(1),根据 Master theorem,a=2, b=2, f(n) = O(1) = O(n^0), 即 c=0.则 T(n) = O(n),具体计算方法参考这篇。
2024-10-31 08:40:26
1188
2
原创 sicp每日一题[2.62]
这道题难度也不大,思路是依次从两个集合中取第一个元素,比较他们的大小,把小的那个和剩下所有元素连接的结果连接起来。由于两个集合中每个元素都只需要取出一次,所以时间复杂度应该是 O(n)。
2024-10-30 08:06:29
160
原创 sicp每日一题[2.61]
就把集合第一个元素和要插入元素和集合其他项连接的结果连接起来就行了。最差的情况就是,要插入的元素比集合最大的元素还要大,这样要遍历整个集合,此时和原来的实现没有区别;在其他情况,平均应该可以节省一半的步骤。这道题实现起来倒是不难,每次比较一下集合第一个元素和要插入的元素的大小,如果要插入的数小于等于集合第一个元素,就直接用 cons 把这个新元素和集合连接起来;如果要插入的元素大于集合第一个元素,
2024-10-29 08:16:24
185
原创 sicp每日一题[2.58]
这道题乍一看很棘手,但是仔细一想其实挺简单的,只要把构造函数和选择器里 + 和 * 的位置改一下就行了,还有原来的前缀表示法要多加一个 + 或 *,现在也可以直接省略掉了。
2024-10-26 13:16:30
424
原创 sicp每日一题[2.57]
这道题挺难的,我理解了题目提示的方法,就是把剩下的项也表示为和或者乘的形式,但是我不明白该怎么实现,递归调用并不能达到要求,最后上网搜了一下才知道怎么做。
2024-10-25 08:31:37
160
原创 sicp每日一题[2.56]
这道题难度不大,先仿照 make-sum, make-product 写出 make-exponentiation 函数,剩下的部分就很简单了。
2024-10-24 08:17:42
826
原创 sicp每日一题[2.52]
对于我来说,这道题最大的难度在于理解题意,我根据自己的理解修改之后想:就这么简单?然后去查了其他人的答案,发现还真就这么简单 :)
2024-10-22 10:43:35
318
原创 sicp每日一题[2.51]
这道题目难度不大,理解了 2.50 那张图后,再仿照 beside 的代码,只要把3个坐标的位置调整一下就可以了;至于利用 beside 和旋转来实现 below,就更简单了,先把2幅图向右旋转90°,然后 beside 排到一起,最后再把排到一起的图形向左旋转90°即可。
2024-10-21 08:46:31
344
原创 sicp每日一题[2.50]
这道题挺有意思的,搞明白这道题就明白了 frame 的3个点的位置。如上图所示,为了更好区分,特意用了长方形而不是正方形,第一幅图是原图,O 表示 origin, A 表示 edge1,B 表示 edge2。无论进行何种变换,左下坐标都是 (0, 0),左上都是(0, 1), 右下都是(1, 0), 右上都是(1, 1),我们只要把变换后的图形中 O, A, B 的新位置作为参数传进去就行。
2024-10-20 09:09:50
701
原创 sicp每日一题[2.49]
上网搜了一下其他人的答案,发现他们都是直接传的 segment-list,而不是传 frame,而且之前定义的 make-vect, make-segment 也都用不了。这道题目我本来感觉不是很难,我按照题目要求把 frame 的3个点坐标取出来,然后用 make-segment 连成线,但是做了半天总是不行,必须先导入 sicp-pict,然后再用它自带的 vect 和 segment 来创建向量和线段。
2024-10-19 12:45:35
685
原创 sicp每日一题[2.45]
然后点击右上角的 run 等待安装完毕重启 DrRacket,再依次点击 Language -> Choose Language,就可以选择看到 SICP(PLaneT 1.18) 了。但是这么简单的方法我用了2个多小时才找到。这道题本身没什么难度,但是我再次遇到了环境问题。之前在台式电脑上装的sicp包,用同样的步骤在笔记本上怎么都不行,卸载重装了好几次,最后参考。的返回值也是一个函数,且它的两个参数分别为。方法其实也不复杂,随便打开一个窗口,输入。,至于实现,仿照原来的。终于找到了解决办法。
2024-10-15 08:20:41
622
原创 sicp每日一题[2.44]
我在这一章遇到了一个大问题,就是书上用的那些函数besidewaveflip−vert我统统用不了。我用的是 DrRacket 这个软件,在网上查了半天,终于找到了解决办法。首先是官方教程,在 DrRacket 中依次打开 File -> Package Manager…,在弹出的页面中 “Do What I Mean” 菜单页的输入:sicp,回车之后自动安装就行了。但是我试了好几次,总是因为网络问题没法下载成功,最后求助于 chatgpt 终于解决了。
2024-10-14 08:17:58
742
原创 sicp每日一题[2.43]
对于练习 2.42 的原方法,每次循环都会减一次,所以一共计算了。遍,对于八皇后问题就是。次,如果原方法时间为。慢的原因比较好理解,
2024-10-13 07:54:02
950
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅