(10分)写一个函数爆炸,给定一个元组列表(n x),通过插入创建一个新列表 x代替(n x)进入列表n次(换句话说,插入的项目应位于同一位置) 创建新列表时,将其作为原始元组排序)。您可以假设n始终为 至少为0。
(爆炸‘(((2“ Hello”)))产生->(“ Hello”“ Hello”)
(爆炸‘(((2“ Hello”)(3“ world”)))产生->(“ Hello”“ Hello” “世界”“世界”“世界”)
到目前为止,我可能想到的一种可能的解决方案是创建一个循环,该循环将跟踪算法当前正在处理的元组,然后在该循环内部具有一个函数定义,该函数定义将被递归调用以将字符串添加到返回列表。但是我不确定这是否行得通,因为似乎需要使用“ set!”。教授说我们不允许使用。
我不是在寻找完整的答案,因为这是一个作业问题。我只想指出正确的方法,也许可以使用一些sudo代码来解决这个问题。
谢谢!
答案 0 :(得分:1)
explode
的空白列表会产生什么?explode
中的'((2 "Hello") (3 "world")))
产生什么?explode
中的'((3 "world"))
产生什么?您如何才能将{3的结果(对cdr的递归调用)与'(2 "Hello")
(列表中的汽车)“结合”起来以产生2的结果?
您可以假设,在构造“ combine”函数时您具有递归调用的结果(combine函数也可能是递归的)。
答案 1 :(得分:0)
将其分为两个问题:
首先,编写一个函数expand
,其功能如下:
(expand 3 "world") => ("world" "world" "world"))
第二,实现explode
,以便对每个参数调用expand
,并将结果附加到单个列表中。
(explode '(x y z ...)) =>
(append (expand (first x) (second x))
(expand (first y) (second y))
(expand (first z) (second z))
...)
两个函数都可以递归。 expand
的基本情况是列表的第一个元素为0
。 explode
的基本情况是列表为空。您需要弄清楚如何将当前结果与对策调用相结合,以针对每个问题产生正确的结果。
答案 2 :(得分:0)
在使用功能语言时,尽量不要考虑循环。
通常,使用循环map可以解决大多数问题,并且可以使用foldr/foldr和reduce(在Racket中使用cppreference)函数来解决。在特殊情况下,当这些功能不够用时,您可以考虑递归。
只需使用map
函数就可以解决您的特定任务:
#lang racket
(define(explode tuples)
(flatten
(map
(lambda (tuple)
(let*
([repeat-n-times (range (first tuple))]
[value (second tuple)])
(map (λ _ value) repeat-n-times)))
tuples)))