首页 > 代码库 > 关于length
关于length
写Scheme代码时,经常要判断表的长度。长度为0时一个操作,长度为1时,另一个操作,长度为2时,第三种操作 ...。最容易想到的方法是(define (length=? m l) (= m (length l)))但这个 length=? 很低效。它要先计算表的长度n。length 的复杂度是O (n),。这个函数的复杂度也是O (n)。改进一实际上表的长度等不等于m,在计算表的长度*时*,就可以确定,不必等到计算表的长度*后*。【不多不少原则】length 可以这样写(define (length l) (if (null? l) 0 (+ 1 (length (cdr l)))))要在计算 length 的时候就判断其长度是否等于 m ,就可以这样写(define (length=? m l) (if (null? l) (zero? m) (length=? (- m 1) (cdr l))))[根据 length 来写 length=? 是很简单的小技巧]改进二上面的改进是考察表的长度得到的。这里我们把另外一参数 m 也考虑进去。高效的 length=? 的复杂度应该是 min (m,n)。也就是说当m比n小时,m步就可以判定了。(define (length=? m l) (cond ((null? l) (zero? m)) ((zero? m) #f) (else (length=? (- m 1) (cdr l)))))类似地,要判断表的长度是否相等就可以这样(define (same-length? l1 l2) (cond ((null? l1) (null? l2)) ((null? l2) #f) (else (same-length? (cdr l1) (cdr l2)))))如果要判断两个以上的表的长度是否相等呢?方法应该还是一样的。1. 如果其中一个表是空表,看其他表是否也都是空表。2. 否则去掉所有表的头部,递归。这就要两个辅助函数 any? 和 all?(define (any? p? ls) (define anyloop (lambda (ls) (if (null? ls) #f (if (p? (car ls)) #t (anyloop (cdr ls)))))) (anyloop ls))(define (all? p? ls) (define allloop (lambda (ls) (if (null? ls) #t (if (not (p? (car ls))) #f (allloop (cdr ls)))))) (allloop ls))(define (same-length? l1 l2 . ls) (define args (cons l1 (cons l2 ls))) (cond ((any? null? args) (all? null? args)) (else (apply same-length? (map cdr args)))))不过这个函数的复杂度,我就不愿意分析了,因为不会呵呵。length=? 也可以作类似扩展。
关于length
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。