你能想到全功能的最短和最惯用的解决方案吗?
;; all-but-one
;; checks if all but one element in a list holds a certain property
;; (all-but-one even? (list 1 2 4)) -> true
;; (all-but-one even? '(1)) -> true
;; (all-but-one even? '(2 4)) -> false
编辑:完全一个。
答案 0 :(得分:5)
如果第一个元素具有指定的属性,则在列表的其余部分调用all-but-one
。
如果第一个元素没有指定的属性,请在列表的其余部分调用all
。
答案 1 :(得分:4)
名字更好:
(define (all-except-one pred l) (= 1 (count (negate pred) l)))
(但这是PLT特定的。)
答案 2 :(得分:2)
PLT解决方案很优雅,通常我更喜欢使用内置的高阶函数而不是编写自己的递归函数。但是如果你想要一个没有分配且没有算术的有效递归解决方案,那么它就是:
(define (all-but-one pred l)
(if (null? l)
#f
((if (pred (car l)) all-but-one all) pred (cdr l))))
递归调用处于尾部位置,因此Scheme和Common LISP都会将此代码编译成紧密循环。有些人可能更喜欢这个等效的代码:
(define (all-but-one pred l)
(if (null? l)
#f
(if (pred (car l))
(all-but-one pred (cdr l))
(all pred (cdr l)))))
答案 3 :(得分:2)
Common Lisp:
(defun all-but-one-p (predicate sequence)
(= 1 (count-if-not predicate sequence)))
示例:
CL-USER 92 > (all-but-one-p #'evenp '(1 2 3))
NIL
CL-USER 93 > (all-but-one-p #'evenp '(1 2 4))
T
如果多个元素为谓词提供否定结果,则此LOOP版本会提前退出。
(defun all-but-one-p (predicate list)
(= 1 (loop with not-pred = (complement predicate)
for item in list count (funcall not-pred item) into counter
when (> counter 1) do (return-from all-but-one-p nil)
finally do (return counter))))
答案 4 :(得分:1)
(define (all-but-one p? xs)
(= (length (filter p? xs)) (- (length xs) 1)))
好的,这个怎么样:不是那么短,而只是一次通过列表。你可以用折叠做同样的事情。
(define (all-but-one p? xs)
(let loop ((len 0) (sat 0) (tmp xs))
(if (null? tmp)
(= sat (- len 1))
(loop (+ len 1)
(if (p? (car tmp)) (+ sat 1) sat)
(cdr tmp)))))
答案 5 :(得分:0)
概括了Anon的想法。
(define (all-but-n n pred lst)
(if (null? lst)
(zero? n)
(if (pred (car lst))
(all-but-n n pred (cdr lst))
(if (zero? n)
#f
(all-but-n (- n 1) pred (cdr lst))))))
(define (all-but-one pred lst) (all-but-n 1 pred lst))
答案 6 :(得分:0)
应该适用于所有体面的Scheme实现的解决方案:
(define (all-but-one? pred values)
(define (count-neg x)
(if (not (pred x)) 1 0))
(let loop ((c 0) (values values))
(if (and (not (null? values))
(<= c 1))
(loop (+ c (count-neg (car values))) (cdr values))
(= c 1))))
答案 7 :(得分:0)
(define (all-but-one? p ls)
(define (all? ls)
(or (null? ls)
(and (p (car ls))
(all? (cdr ls))))
(define (loop ls)
(cond ((null? ls) #f)
((p (car ls)) (all? (cdr ls)))
(else (loop (cdr ls)))))
(loop ls))