如何解决cdr不理解空列表?

时间:2014-09-13 01:28:36

标签: scheme

我的问题是butSecondLastAtom算法。它不起作用,因为cdr不理解空列表。但我没有看到编写算法的其他方法。它位于页面的末尾。一切都有效但列表的最后一个元素是列表。 http://lpaste.net/110959

问题在于(cdr(cdr l))的递归调用,但在第3个条件中更多。 Idk该做什么。我今晚要停下来,早上开始新鲜。

((and (isAtom (second_last_element l)) (notAtom (last_element l)))
        (cons
           (car l)
             (butSecondLastAtom (last_element l))))

1 个答案:

答案 0 :(得分:0)

我认为您的代码中的主要问题是在null?和{{1}中的列表的cdr上使用cdrflatten }。不要这样做;始终使用列表本身的过程和谓词。

我建议如下:

展平列表

大多数方案都有butLast内置版本,它负责嵌套列表不正确列表。您实施的版本不完全正确(尝试flatten),请使用此版本:

(flatten '())

删除最后一个元素

因此,现在变得更加容易,循环浏览一个简单的平坦正确列表,同时跟踪最后一个((define (flatten lst) (let loop ((lst lst) (res null)) (cond ((null? lst) res) ((pair? lst) (loop (car lst) (loop (cdr lst) res))) (else (cons lst res))))) > (flatten '(1 2 (3 (4 5 6)))) '(1 2 3 4 5 6) > (flatten '(1 2 (3 (4 5 (6))))) '(1 2 3 4 5 6) > (flatten '()) '() )和倒数第二个(n-1)元素。示例实现是:

n-2

如果你想避免两次通过列表(一次用于(define (butSecondLastAtom lst) (define flst (flatten lst)) (if (< (length flst) 2) flst (let loop ((flst (cddr flst)) (n-2 (car flst)) (n-1 (cadr flst)) (res null)) (if (null? flst) (reverse (cons n-1 res)) ; here we drop the second-last element (loop (cdr flst) n-1 (car flst) (cons n-2 res)))))) ,一次用于循环),你也可以自己跟踪长度:

length

测试

(define (butSecondLastAtom lst)
  (define flst (flatten lst))
  (let loop ((lst flst) (len 0) (n-2 #f) (n-1 #f) (res null))
    (if (null? lst)
        (if (< len 2)
            flst
            (reverse (cons n-1 res))) ; here we drop the second-last element
        (loop (cdr lst) (add1 len) n-1 (car lst) (if (< len 2) null (cons n-2 res))))))
相关问题