计算机程序的构造和解释 练习题3.19

开始想的解题思路就是判断第一个序对是否在后面每个序对的cdr中,是的话就是个环,但是这个有个问题,如果一个序列,除过第一个元素,后面的元素组成一个环,这个就变成死循环了。

#lang R5RS

(define (last-pair x)
  (if (null? (cdr x))
      x
      (last-pair (cdr x))))

(define (make-cycle x)
  (set-cdr! (last-pair x) x)
  x)

(define (element-cdr-of-set? x set)
  (cond ((not (pair? set)) #false)
        ((eq? x (cdr set)) #true)
        (else (element-cdr-of-set? x (cdr set)))))

(define (adjoin-set x set)
  (cons x set))

(define (is-cycle? x)
  (cond ((not (pair? x)) #false)
        ((element-cdr-of-set? x (cdr x)) #true)
        (else (is-cycle? (cdr x)))))

(define z (make-cycle (list 'a 'b 'c)))
(display z)
(newline)
(display (is-cycle? z))
(newline)
(define z1 (list 'a 'b 'c))
(display z1)
(newline)
(display (is-cycle? z1))

运行结果

#0=(a b c . #0#)
#t
(a b c)
#f

于是换用第二种思路,也叫“快慢指针”,用两个变量一起遍历序列,一个一次遍历两个,一个一次遍历一个,如果两个变量相遇,就判定是一个环,如果遍历两个的那个变量先到达终点,则不是一个环。
下面是这种思路的代码

#lang R5RS

(define (last-pair x)
  (if (null? (cdr x))
      x
      (last-pair (cdr x))))

(define (make-cycle x)
  (set-cdr! (last-pair x) x)
  x)

(define (is-cycle? x)
  (define (is-cycle-two? x1 x2)
  (cond ((not (pair? x2)) #false)
        ((not (pair? (cdr x2))) #false)
        ((eq? x1 x2) #true)
        (else (is-cycle-two? (cdr x1) (cddr x2)))))
  (if (not (pair? x)) #false
      (is-cycle-two? x (cdr x))))

       
(define z (make-cycle (list 'a 'b 'c)))
(display z)
(newline)
(display (is-cycle? z))
(newline)
(define z1 (list 'a 'b 'c))
(display z1)
(newline)
(display (is-cycle? z1))

运行结果

#0=(a b c . #0#)
#t
(a b c)
#f
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值