(方案)如何在列表中重复添加(或多个)元素?

时间:2013-04-27 02:26:18

标签: list scheme

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

3 个答案:

答案 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: '() ))))