如何修改Scheme的tsar函数实现列表中RANDOM符号替换为0-100随机数
背景
我目前有如下Scheme程序:
(define (tsar subj srch repl) (cond ((list? subj) (map (lambda (lst) (tsar lst srch repl)) subj)) (else (if (equal? subj repl) srch subj))))
该函数接收三个参数:待处理对象subj(通常为列表)、搜索值srch、替换值repl,作用是递归遍历列表,将所有等于repl的原子替换为srch。
当前该函数运行正常,例如:(display(tsar '(1 2 () 4 (7 (7 (3 7)))) '() 3))
运行结果为:(1 2 () 4 (7 (7 (() 7))))
列表中的原子3如预期被替换为了()。
问题需求
现在需要扩展该函数的功能:当列表中存在符号RANDOM时,需要调用(random 100)将其替换为0到100之间的随机数。
现有思路
我认为可以使用eq?之类的判断来识别原子是否为RANDOM,也猜测可以递归调用tsar函数,传入待处理列表作为subj、RANDOM作为srch、(random 100)作为repl来实现需求。但我刚接触Scheme和函数式编程,不知道具体该如何实现,特此咨询。
补充说明:RANDOM是符号类型,不是字符串。
解决方案
直接在原有函数的原子判断分支新增RANDOM符号的识别逻辑即可,原有功能完全保留,修改后代码如下:
(define (tsar subj srch repl) (cond ((list? subj) (map (lambda (lst) (tsar lst srch repl)) subj)) (else (cond ((eq? subj 'RANDOM) (random 100)) ((equal? subj repl) srch) (else subj)))))
修改说明
- 符号对比用
eq?即可,Scheme中同名字符串的符号是唯一实例,eq?对比指针地址的效率远高于通用的equal? - 原有替换逻辑没有改动,之前的调用方式不受任何影响
测试示例
执行调用:
(display (tsar '(1 RANDOM 3 (7 (RANDOM 3))) '() 3))
输出示例(随机数部分每次运行结果不同):
(1 47 () (7 (29 ())))
可以看到所有RANDOM都被替换为0-99的随机数,原有3替换为()的逻辑也正常生效。
内容的提问来源于stack exchange,提问作者Banani720
相关产品推荐
相关产品推荐

