2016-10-30 73 views
1

因此,我已經完成了創建一個過程的任務,該過程爲您提供了需要在該列表中找到的兩個字母和一個列表。我開始編寫程序,但很快就偶然發現了一些錯誤。我的代碼如下:在計劃中計算列表中的多個連續字母

(define (count-2-consecutive x y lst) 
     (define (iter ctr lst) 
     (cond ((null? lst) '()) 
       ((and (eq? x (car lst)) (eq? y (cadr lst))) (count-2-consecutive x y (cdr lst))) 
       (else (count-2-consecutive x y (cdr lst))))) 
     (iter 0 lst)) 

所以,當我嘗試運行一個實例(如:(count-2-consecutive 'n 't '(h o t t e n t o t t e n t e n t e n))我收到了「違反合同」的錯誤,在我在我的代碼中使用的cadr指着我。如果有人可以幫助我指出我做錯了,我會非常感激。

回答

0

爲了使用(cadr xs)你需要知道的是,名單xs至少有兩個元素。您使用測試(null? xs)使確保列表xs有一個元素。在你的cond中添加一個額外的子句,用(null? (cdr xs))來處理單元素列表。

(define (count-2-consecutive x y lst) 
     (define (iter ctr lst) 
     (cond ((null? lst) '()) 
       ((null? (cdr lst)) SOMETHING) 
       ((and (eq? x (car lst)) (eq? y (cadr lst))) (count-2-consecutive x y (cdr lst))) 
       (else (count-2-consecutive x y (cdr lst))))) 
     (iter 0 lst)) 
0

你也可以使用for/sum循環這裏:

(define (f x y l) 
    (for/sum ((i (sub1 (length l))) 
      #:when (and (equal? (list-ref l i) x) 
         (equal? (list-ref l (add1 i)) y))) 
    1)) 

測試:

(f 1 2 '(0 1 2 3 1 2 5)) 
(f 1 2 '(0 1 3 1 2 5)) 
(f 1 2 '(0 4 3 5 8)) 

輸出:

2 
1 
0 

你也可以測試使用take功能列表來獲得2項的子清單與x和y比較:

(define (f x y l) 
    (let loop ((l l) 
      (cntr 0)) 
    (cond 
     [(< (length l) 2)     cntr] 
     [(equal? (take l 2) (list x y)) (loop (rest l) (add1 cntr))] 
     [else        (loop (rest l) cntr)])))