不正当和。 Scheme中的正确列表

时间:2014-05-13 07:22:38

标签: list scheme cons

我尝试实现的原始代码..输出应该是我的代码中的(1.4)(2.5)..我想你们都知道我尝试做什么....这也是尾递归练习

my code
(define (myFunc lst1 lst2)
 (if (or (null? lst1) (null? lst2))       
    '()                                  
     (list (cons (car lst1) (car lst2))
        (myFunc (cdr lst1) (cdr lst2)))
  ))

你们几个人给了我good advice关于cons-pair ..所以现在它得到了中间的虚线符号..然后问题是最后列出空列表的不正确的列表..  当2个输入列表是这样的时候.....'(1 2 3 4)'(4 5 6)) 我的输出是这样的; ((1.4)((2.5)((3.6)()))) 输出结尾的空列表不应该存在...所以我无法理解不正确的列表,正确的列表....?是否有任何文件,我可以看看?

2 个答案:

答案 0 :(得分:2)

考虑conslist

之间的区别

cons vs. list

也就是说,(cons a b)会创建一个caracdrb的单元格。 (list a b)创建的cara的广告单元,cdr列表car列表为b,而cdrnil

如果b是一个列表,则左侧的列表将是一个列表,其尾部有b,并且在a的前面添加了b
右边的那个也是一个列表,但是b作为第二个元素,而不是你想要的尾巴。

要修复您的计划,您只需将list替换为cons即可。

但是你的函数不是尾递归的,因为它用递归调用的结果做事。

为了使它具有尾递归,一个好方法通常是创建一个具有累加器参数的辅助函数。

我可能会这样写:

(define (zip-cars l1 l2)
    (cons (car l1) (car l2)))

(define (zip-help l1 l2 result)
    (if (or (null? l1) (null? l2))
        result
        (zip-help (cdr l1) (cdr l2) (cons (zip-cars l1 l2) result))))

(define (zip l1 l2)
    (zip-help l1 l2 '()))

答案 1 :(得分:1)

只需将list替换为cons即可。然后你的代码将评估为`(cons(cons(cons(cons ....(cons ...'(())),你的列表将被正确终止。

(define (zip lst1 lst2)
  (if (or (null? lst1) (null? lst2))       
      '()                                  
      (cons (cons (car lst1) (car lst2))
            (zip (cdr lst1) (cdr lst2)))))

然后

(zip '(1 2 3 4) '(4 5 6))
=> '((1 . 4) (2 . 5) (3 . 6))

这不是尾递归,因为从zip返回后,仍然需要完成。

修改

尾递归版本的示例:

(define (zip lst1 lst2)
  (let loop ((lst1 lst1) (lst2 lst2) (res '()))
    (if (or (null? lst1) (null? lst2))       
        (reverse res)
        (loop (cdr lst1) 
              (cdr lst2) 
              (cons (cons (car lst1) (car lst2)) res)))))