解决方案中的奇数重复

时间:2016-12-29 11:15:42

标签: scheme lisp

我尝试在方案中仅输出列表中的非重复元素来解决问题。例如:'(a b a a a c c)会给(a b)

我已经实施了这个解决方案:

(define (remove L)  
  (if (null? L)
      L
      (let ((firstL (car L)) (restL (cdr L)))        
        (if (null? restL)
            (cons firstL ())
            (if (equal? firstL (car restL))
                (remove (cdr restL))                
                (cons firstL (remove restL)))))))

然而,它也输出具有奇数重复次数的元素。例如:(a b a a c c)会给(a b a)。

我试图解决它,但我无法解决。我尝试过的一个解决方案的例子是:

(define (remove L)  
  (if (null? L)
      L      
      (let ((result ()) (firstL (car L)) (restL (cdr L)))        
        (if (null? restL)
            (result)            
            (if (equal? firstL (car restL))
                (remove2 firstL restL)                
                (append ((list firstL) result))
                (remove cdr restL)))))

  (define (remove2 x y)
    (cond ((null? y) (remove x)
                     ((equal? x (car y)) (remove2 ((car y) (cdr y))))                     
                     (else (remove x)))))

如果有人可以找到解决方案,请写下来。

2 个答案:

答案 0 :(得分:0)

你的第二次尝试有很多语法错误。我想如果你看一下第一次尝试并用缺少的引用'()修补一个语法错误,如果你可以删除连续的元素而不是只有一个,你几乎可以使用它。例如。使

(trim-first '(a b c))     ; ==> (b c)
(trim-first '(a a b c))   ; ==> (b c)
(trim-first '(a a a b c)) ; ==> (b c)

然后您可以使用它代替cdr

(define (remove L)  
  (if (null? L)
      L
      (let ((firstL (car L)) (restL (cdr L)))        
        (if (null? restL)
            (cons firstL '())
            (if (equal? firstL (car restL))
                (remove (trim-first restL))                
                (cons firstL (remove restL)))))))

我会用cond写出来让它更平坦但是远离非传统的camelCase而转而支持lisp-case

(define (remove-runs lst)
  (cond ((null? lst) '())
        ((null? (cdr lst)) lst)
        ((equal? (car lst) (cadr lst)) (remove-runs (trim-first (cdr lst))))
        (else (cons (car lst) (remove-runs (cdr lst))))))

答案 1 :(得分:0)

以下是在Racket(Scheme衍生物)中的解决方案,使用"命名为let"递归。发送的列表被分为'((a)(b)(a a a)(c c))的组件,然后只有那些只有一个项目的子列表:

(define (f l)
  (let loop ((l (rest l))              ; first item removed from sent list
             (ol '())        ; store repeating sequences here as separate lists
             (temp (list(first l))))   ; keep first item in temp
    (cond
      [(empty? l)                      ; end reached
       ; (println (cons temp ol))      ; here temp+ol is '((c c)(a a a)(b)(a))
       (reverse
        (flatten
         (filter
          (λ (x) (= 1 (length x)) )    ; take only those which have only one item
          (cons temp ol))))]
      [(equal? (first l) (first temp)) ; if item repeats, store together
       (loop (rest l)
             ol
             (cons (first l) temp) )]
      [else                            ; else put temp in ol & start new temp
       (loop (rest l)
             (cons temp ol)
             (list (first l)))])))

测试:

(f '(a b a a a c c))  

输出:

'(a b)