我有我的茶,我的代碼審查帽子和幾分鐘的空閒時間。你知道現在幾點了。
你想要的是一個謂詞,它會告訴你是否有列表中第一個原子的重複。
(define (doubles a_list)
(cond ((null? a_list) #t)
(not ((eq? (car a_list) (car (cdr a_list)))) (doubles(cdr a_list)))
無論其他什麼,這不會工作,因爲它有不平衡的括號。
(define (doubles a_list)
(cond ((null? a_list) #t)
(not ((eq? (car a_list) (car (cdr a_list)))) (doubles(cdr a_list)))))
這個修訂版將無法工作,因爲它在case
畸形的第二句話。奇怪的是,它似乎評價很好,但是當你調用它,你會得到一個奇怪的錯誤信息
Welcome to Racket v5.3.6.
> (define (doubles a_list)
(cond ((null? a_list) #t)
(not ((eq? (car a_list) (car (cdr a_list)))) (doubles(cdr a_list)))))
> (doubles (list 1 2 3 4 5 6 7 3))
application: not a procedure;
expected a procedure that can be applied to arguments
given: #f
arguments...: [none]
>
的直接原因是由於圍繞這一額外的括號的該位
... ((eq? (car a_list) (car (cdr a_list)))) ...
表達,它實際上意味着什麼
「看看a_list
的第一個元素是否與第二個元素相同,然後將該檢查的結果作爲函數調用」。
這不是你想要的。正確的分辨率是not
到這些parens,這將使有效的cond
條款。
(define (doubles a_list)
(cond ((null? a_list) #t)
((not (eq? (car a_list) (car (cdr a_list))))
(doubles (cdr a_list)))))
不能在方案空列表上調用car
。這對Common Lisp中的「fine」的一些定義很好,但會在這裏給你一個錯誤。
> (define (doubles a_list)
(cond ((null? a_list) #t)
((not (eq? (car a_list) (car (cdr a_list))))
(doubles (cdr a_list)))))
> (doubles (list 1 2 3 4 5 6 7 3))
car: contract violation
expected: pair?
given: '()
>
此錯誤的原因是,你檢查a_list
是否null?
,但再後來就打電話(car (cdr a_list))
。在a_list
類似於(3)
的情況下,您會收到此錯誤。對此問題進行修復正在檢查是否a_list
或其cdr
現在null?
(define (doubles a_list)
(cond ((or (null? a_list) (null? (cdr a_list))) #t)
((not (eq? (car a_list) (car (cdr a_list))))
(doubles (cdr a_list)))))
> (doubles (list 1 2 3 4 5 6 7 3))
#t
,我們已經有了一個版本的功能不報錯了,讓我們看看你的邏輯。在列表中找到雙打的過程
- 的長度爲零或一個名單,答案是假的,因爲不可能有雙打列表中的短於兩個元素
- 否則,檢查第一清單中的元素在其餘部分。
- 如果是,答案是真實的,因爲我們已經發現重複
現在,你已經命名的功能doubles
,但你的散文的解釋告訴我,這真的應該已經unique-first?
。因爲你不是在尋找雙打,你的目的是要檢查你的列表中的第一個元素是否在同伴中是唯一的。你真正想要做的是
- 的長度爲一的名單,答案是正確的,因爲是單一的元素必須是唯一的(我會假設你想要的長度爲零的列表相同,但根據應用程序可能沒有實際意義)
- 否則,請檢查列表的第一個元素是否不在其餘。
這相當於
(define (unique-first? a_list)
(if (or (null? a_list) (null? (cdr a_list)))
#t
(not (member? (car a_list) (cdr a_list)))))
的member?
功能是相當簡單的,並且適用於同樣的原則。
(define (member? elem lst)
(cond ((null? lst) #f)
((eq? elem (car lst)) #t)
(else (member? elem (cdr lst)))))
最後,一對夫婦的造型加分。 Scheme的慣例是命名帶有尾部?
的謂詞,它會向您的函數的調用者暗示它將返回#t
或#f
(我已經完成了上述操作),並且使用spinal-case
而不是snake_case
作爲名稱。
(define (unique-first? a-list)
(if (or (null? a-list) (null? (cdr a-list)))
#t
(not (member? (car a-list) (cdr a-list)))))
主席先生,在您的許可下,我是否可以採用您的命名慣例爲'unique-first?'? :) – xbug 2014-11-21 16:49:10
@xbug - 當然。去堅果:) – Inaimathi 2014-11-21 16:56:08
非常感謝:-) – xbug 2014-11-21 16:57:43