这个函数应该是两个用l一起表示的一元数列表的多个。由于乘法只是重复添加,我创建了一个添加列表的函数,并使用此函数循环它直到它到达其中一个列表的末尾。
例如:
~ (um1 '(l l l) '(l l))
(l l l l l l) <--- 3 * 2 = 6
问题在于它没有正确循环。它增加了很多额外的数字。帮助
;adds ls1 and ls2
(define (uadd ls1 ls2)
(if (null? ls1) ls2
(cons (car ls1) (uadd (cdr ls1) ls2))))
;multiplies ls1 and ls2
(define (um1 ls1 ls2)
(define (help ls1 ls2 i)
(if (<= i (length ls2))
(help (uadd ls1 ls1) ls2 (add1 i))
ls1))
(help ls1 ls2 0))
PS:很抱歉问了这么多问题。我真的在我的计算机科学课上苦苦挣扎。
答案 0 :(得分:0)
(a+1)*b = b + a*b
。用那个。
你这样做:a*b = (h a b 0) = if (i<b) then (h (a+a) b (i+1)) else a
。抱歉,这对我没有意义。您在help
的每次迭代中将第一个arg加倍,然后迭代b
次。这似乎计算2^b*a
。
你的第一个代码很好。你的第二个受到 shadowing 的影响 - 你的帮助器中的参数与主函数中的名称相同,而你打算使用的名称最终使用另一个。重命名变量,一切都会很好:
;multiplies ls1 and ls2
(define (um1 ls1 ls2)
(define (help a b i)
(if (< i (length b))
(help (uadd a ls1) b (add1 i))
a))
(help ls1 ls2 1))
这当然可以在效率方面得到很大改善。您无需将ls2
传递给帮助程序,也无需一直重新计算其长度。不要忘记a*0 = 0
。
答案 1 :(得分:0)
如果我们回到乘法的定义这很简单 - 它是一个缩写的总和。什么是(um1 '(l l l) '(l l))
?与'(l l l)
追加到'(l l l)
相同。这里不需要定义帮助器,甚至不需要使用uadd
- 技巧是知道如何将列表组合在一起以形成具有两者的元素的列表(提示:这我们不< / em>使用cons
),并根据需要多次重复此过程。
假设第一个列表要“重复”多次,等于第二个列表中元素的数量 - 当第二个列表用完元素时,递归将结束。你知道演习,填空:
(define (um1 ls1 ls2)
(if <???> ; if the list we're recurring over is empty
<???> ; ... you know what to return
(<???> <???> ; otherwise add one copy of the list we're repeating
(um1 <???> <???>)))) ; and advance the recursion over the correct list
不要忘记测试程序,注意当其中一个列表为空时会发生什么:
(um1 '() '())
=> '()
(um1 '(l) '())
=> '()
(um1 '() '(l))
=> '()
(um1 '(l) '(l l))
=> '(l l)
(um1 '(l l) '(l))
=> '(l l)
(um1 '(l l l) '(l l))
=> '(l l l l l l)
(um1 '(l l) '(l l l))
=> '(l l l l l l)
答案 2 :(得分:0)
有一个更容易的方法来做这个比一个额外的帮助 - 你的“uadd”程序是你的帮助。
什么是乘法?
“3 * 4 = 12”或“a * b = c”
“3 + 3 + 3 + 3 = 12”或“a + a + a + a = c”或“a值自身增加b次数等于c”
因此,我们的伪代码:
“如果ls1或ls2 = 0(或为null),答案为0(或为空)”&lt; - BASE CASE
“否则,将ls1添加到自身&amp;删除并减少ls2,直到ls2中没有任何内容”&lt; - RECURSION
将它拼凑在一起:
(define um1
(lambda (ls1 ls2)
(cond
[(or (null? ls1) (null? ls2)) '()] ;BASE
[else (uadd ls1 (um1 ls1 (cdr ls2))]))) ;RECURSION
在我们的尾递归中,我们只希望将ls2减1,直到它为'(),在这种情况下,我们的BASE CASE捕获它并提供一个'(),其顶部堆叠一个ls2-number of
(uadd ls1 (uadd ls1 (uadd ls1 (...ls2-number-of-times, until: '() ))))