2

这个函数应该将两个用 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:不好意思问了这么多问题。我在计算机科学课上真的很挣扎。

4

3 回答 3

0

有一种比使用额外助手更简单的方法 - 您的“uadd”过程就是您的助手。

什么是乘法?

“3*4=12”或“a*b=c”

"3+3+3+3=12" or "a+a+a+a=c" or "a value added itself ab number of times equals c"

因此,我们的伪代码:

“如果 ls1 或 ls2 = 0(或 null),则答案为 0(或 null)”<--基本案例

“否则,将 ls1 添加到自身并删除并减少 ls2,直到 ls2 中什么都没有” <-- 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 捕获它并提供一个 '()

(uadd ls1 (uadd ls1 (uadd ls1 (...ls2-number-of-times, until: '() ))))
于 2013-10-08T04:43:45.430 回答
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,然后迭代b次数。这似乎可以计算2^b*a

你的第一个代码很好。你的第二个受到阴影的影响- 你的助手中的参数名称与你的主要函数中的名称相同,并且你打算使用一个你最终使用另一个。重命名变量,一切都会好起来的:

;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

于 2013-04-27T02:35:30.650 回答
0

如果我们回到乘法的定义,这很简单——它是一个简写的和。是什么(um1 '(l l l) '(l l))'(l l l) 与附加到相同'(l l l)。不需要在这里定义一个助手,甚至没有必要使用uadd- 诀窍是知道如何将列表组合在一起以形成一个包含两者元素的列表(提示:我们没有使用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)
于 2013-04-27T02:51:25.007 回答