如何在Scheme中递归遍历单个列表并查找和为0的元素对?
查找列表中和为0的元素对(受限构造)
需求与困境
需要遍历列表,检查是否存在任意一对元素和为0,找到则返回#t,遍历完无匹配则返回#f。可使用的构造仅限null?、car、cdr、cons、else,禁止嵌套COND或定义变量。
当前实现仅能比较相邻元素,无法让列表的第一个元素(如测试用例'(5 6 -5)中的5)与后续所有元素(如-5)进行比较,导致测试用例无法返回正确结果。
当前代码
(define add (lambda (lst) (cond ;Null check ((null? (cdr lst)) #f) ;Adds car and car of cdr to check for 0. ((= 0 (+ (car lst) (car(cdr lst)))) #t) ;Recursive portion ((car lst) (sum (cdr lst))) **Not having any luck with this part. ))) (sum '(5 6 -5))
解决方案
要实现每个元素与后续所有元素的比较,需要两层递归逻辑:一是让当前元素依次和剩余所有元素比对,二是遍历后续元素作为新的当前元素重复检查。以下是符合限制的实现:
(define has-zero-pair (lambda (lst) (cond ((null? lst) #f) ; 空列表无配对 ((null? (cdr lst)) #f) ; 单元素列表无配对 ((= 0 (+ (car lst) (car (cdr lst)))) #t) ; 检查当前元素与下一个元素 (else (or (has-zero-pair (cons (car lst) (cdr (cdr lst)))) ; 保留当前元素,和后续元素继续比对 (has-zero-pair (cdr lst))))))) ; 切换到下一个元素作为当前元素,重复检查
逻辑说明
- 边界处理:空列表或仅含一个元素的列表直接返回
#f,无配对可能。 - 相邻检查:先检查当前第一个元素与第二个元素的和是否为0,是则立即返回
#t。 - 递归扩展:
- 第一种递归:通过
cons (car lst) (cdr (cdr lst))构造新列表,保留当前第一个元素,去掉第二个元素,继续让当前元素和后续所有元素比对。 - 第二种递归:去掉当前第一个元素,以剩余子列表为对象重复整个检查流程。
- 第一种递归:通过
- 逻辑或合并:只要任意一层递归找到配对,整体就返回
#t,确保不会遗漏任何可能的元素对。
测试用例(has-zero-pair '(5 6 -5))会返回#t,符合预期。
内容的提问来源于stack exchange,提问作者airhead_249
相关产品推荐
相关产品推荐

