我的问题是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))))
答案 0 :(得分:0)
我认为您的代码中的主要问题是在null?
和{{1}中的列表的cdr
上使用cdr
或flatten
}。不要这样做;始终使用列表本身的过程和谓词。
我建议如下:
展平列表
大多数方案都有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))))))