用 Lisp 语言计算一个集合的所有子集构成的新集合

函数 (aleph L) 的参数 L 是一个集合,返回值是以该集合的所有子集为元素,构成的新集合。函数 (aleph-n L n) 则是对 (aleph L) 的多次递归调用。

以下代码在 DrRacket 下编译通过。

#lang racket

;当n等于1时,aleph-n返回集合L的所有子集构成的集合。当n大于1时,则进行多次迭代操作。
(define (aleph-n L n) 
  (cond ((empty? L) '()) 
        ((<= n 0) L)
        ((= n 1) (aleph L))
        (#t (aleph (aleph-n L (- n 1))))))

;aleph返回集合L的所有子集构成的集合
(define (aleph L)
  (define (aleph-temp L k L-sum)
    (if (> k 0)
        (aleph-temp L (- k 1) (connect (combination L k) L-sum))
        L-sum))
  (aleph-temp L (length L) '()))

;返回集合L的所有大小为n的子集构成的集合
(define (combination L n)
  (define (f L1 L2 k i ret)
    (if (> k 0)
        (g f L1 L2 k i ret)
        (connect ret (cons L1 '()));(print L1)
        ))
  (define (g f L1 L2 k i ret)
    (cond ((<= i (length L2)) 
           (g f L1 L2 k (+ i 1) 
              (f
               (connect L1 (cons (element-at L2 i) '()))
               (connect (sub-list L2 1 (- i 1)) (sub-list L2 (+ i 1) (length L2)))
               (- k 1)
               i
               ret)))
          (#t ret)))
  (cond ((<= n 0) '(()))
        ((>= n (length L)) (cons L '()))
        (#t (g f '() L n 1 '()))))

;返回序列L的第n个元素
(define (element-at L n)
  (cond
    ((< n 1) '())
    ((> n (length L)) '())
    ((= n 1) (car L))
    (#t (element-at (cdr L) (- n 1)))))

;返回L中从s到t的元素构成的新列表,其中 s>=1,t<=(length L)。
(define (sub-list L s t)
  (define (sub-head L t)
    (if (> t 0)
        (cons (car L) (sub-head (cdr L) (- t 1)))
        '()))
  (define (sub-tail L s)
    (if (> s 1) 
        (sub-tail (cdr L) (- s 1))
        L))
  (if (> s t) 
      '()
      (sub-tail (sub-head L (min t (length L))) (max s 1))))

;将两个列表L1和L2连接起来
(define (connect L1 L2)
  (if (empty? L1) 
      L2
      (cons (car L1) (connect (cdr L1) L2))))

以下是对 L={a,b} 的计算结果演示:

> (aleph-n '(a b) 1)
'((a) (b) (a b))

> (aleph-n '(a b) 2)
'(((a)) ((b)) ((a b)) ((a) (b)) ((a) (a b)) ((b) (a b)) ((a) (b) (a b)))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值