2009-03-29 40 views
5

Tôi có một danh sách các phần tử '(a b c) và tôi muốn tìm nếu (đúng hay sai) x ở trong đó, trong đó x có thể là' a hoặc 'd, chẳng hạn. Có chức năng tích hợp cho điều này không?Chức năng Đề án để tìm một phần tử trong danh sách là gì?

+0

Sử dụng các tài liệu tham khảo ngôn ngữ để tìm thấy nó: http://schemers.org/Documents/Standards/R5RS//HTML/r5rs-ZH-9.html#%_sec_6.3.2 –

Trả lời

21

Nếu bạn cần so sánh bằng cách sử dụng một trong các nhà khai thác tương đương, bạn có thể sử dụng memq, memv, or member, tùy thuộc vào việc bạn muốn tìm kiếm sự bình đẳng bằng cách sử dụng eq?, eqv?, or equal?, tương ứng.

> (memq 'a '(a b c)) 
'(a b c) 
> (memq 'b '(a b c)) 
'(b c) 
> (memq 'x '(a b c)) 
#f 

Như bạn có thể thấy, các hàm này trả về danh sách con bắt đầu từ phần tử khớp đầu tiên nếu chúng tìm thấy phần tử. Điều này là do nếu bạn đang tìm kiếm một danh sách có thể chứa boolean, bạn cần phải có khả năng phân biệt trường hợp tìm kiếm #f từ trường hợp không tìm thấy phần tử bạn đang tìm kiếm. Một danh sách là một giá trị đúng (chỉ có giá trị sai trong Đề án là #f), do đó bạn có thể sử dụng kết quả của memq, memv, hoặc member trong bất kỳ bối cảnh chờ đợi một boolean, chẳng hạn như là một biểu if, cond, and, hoặc or.

> (if (memq 'a '(a b c)) 
    "It's there! :)" 
    "It's not... :(") 
"It's there! :)" 

Sự khác nhau giữa ba hàm khác nhau là gì? Nó dựa trên chức năng tương đương mà họ sử dụng để so sánh. eq? (và do đó memq) kiểm tra nếu hai đối tượng là cùng một đối tượng cơ bản; về cơ bản nó tương đương với so sánh con trỏ (hoặc so sánh giá trị trực tiếp trong trường hợp các số nguyên). Do đó, hai chuỗi hoặc danh sách trông giống nhau có thể không phải là eq?, bởi vì chúng được lưu trữ ở các vị trí khác nhau trong bộ nhớ. equal? (và do đó member?) thực hiện so sánh sâu về danh sách và chuỗi, và về cơ bản, bất kỳ hai mục nào in giống nhau sẽ là equal?.eqv? giống như eq? cho hầu hết mọi thứ trừ số; cho con số, hai số đó là số lượng tương đương sẽ luôn luôn được eqv?, nhưng họ có thể không eq? (điều này là vì bignums và số hữu tỉ, trong đó có thể được lưu trữ trong những cách như vậy mà họ sẽ không eq?)

> (eq? 'a 'a) 
#t 
> (eq? 'a 'b) 
#f 
> (eq? (list 'a 'b 'c) (list 'a 'b 'c)) 
#f 
> (equal? (list 'a 'b 'c) (list 'a 'b 'c)) 
#t 
> (eqv? (+ 1/2 1/3) (+ 1/2 1/3)) 
#t 

(Lưu ý rằng một số hành vi trong những chức năng là undefined bởi các đặc điểm kỹ thuật, và do đó có thể khác với thực hiện để thực hiện; tôi đã bao gồm ví dụ mà nên làm việc trong bất kỳ R RS tương thích Scheme mà thực hiện con số chính xác hợp lý)

Nếu bạn cần tìm kiếm một mục trong danh sách bằng cách sử dụng một vị từ tương đương e khác với một trong những xây dựng trong những người thân, sau đó bạn có thể muốn find hoặc find-tail từ SRFI-1:

> (find-tail? (lambda (x) (> x 3)) '(1 2 3 4 5 6)) 
'(4 5 6) 
+0

Tên hàm 'memq' viết tắt là gì? – Freewind

+1

'memq' là một trong những thành viên' gia đình 'chức năng, tìm kiếm một mục trong một danh sách dựa trên một số loại tương đương (như những người khác đã đề cập, 'thành viên' và' memv'). 'Q',' v', hoặc tên đầy đủ kết nối nó với ba hàm tương đương mà chúng sử dụng; 'memq' sử dụng' eq? 'để kiểm tra sự tương đương,' memv' sử dụng 'eqv?' để kiểm tra sự tương đương, và 'thành viên' sử dụng' bằng? 'để kiểm tra sự tương đương. Xem tài liệu liên kết về các hàm tương đương cho sự khác biệt giữa chúng. –

+0

Cảm ơn bạn! Vì vậy, 'memq' có thể được coi là' mem-q', và 'memv' là' mem-v' – Freewind

0

Bạn đang tìm kiếm "tìm"

Khái niệm cơ bản - Các trường hợp đơn giản nhất là chỉ cần (tìm nhập danh sách), thường được sử dụng như một vị: "là nhập trong Danh mục sách?". Nếu thành công trong việc tìm kiếm phần tử được đề cập, nó trả về phần tử khớp đầu tiên thay vì chỉ là "t". (Trích từ liên kết thứ hai.)

http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node145.html

-hoặc-

http://www.apl.jhu.edu/~hall/Lisp-Notes/Higher-Order.html

+0

Câu hỏi đặt ra là về Đề án, không Lisp thường gặp. –

+0

Vâng, ông đã gắn thẻ LISP. –

+0

Đọc tiêu đề: 'Chức năng SCHEME để tìm một phần tử trong danh sách là gì?'. Đề án là một phương ngữ trong gia đình của ngôn ngữ Lisp. –

3

Dưới đây là một cách:

> (cond ((member 'a '(a b c)) '#t) (else '#f)) 
#t 
> (cond ((member 'd '(a b c)) '#t) (else '#f)) 
#f 

thành viên trả về tất cả mọi thứ bắt đầu từ nơi nguyên tố này là hoặC#f. Một cond được sử dụng để chuyển đổi thành true hoặc false.

+0

'# t' cũng tốt, thay vì' '# t' –

0

Tôi không biết nếu có một xây dựng trong chức năng, nhưng bạn có thể tạo một:

(define (occurrence x lst) 
     (if (null? lst) 0  
      (if (equal? x (car lst)) (+ 1 (occurrence x (cdr lst))) 
            (occurrence x (cdr lst)) 
      ) 
     ) 
) 

Ỳạn sẽ nhận lại số lần xuất hiện của x trong danh sách. bạn cũng có thể mở rộng nó với true hoặc false.

Các vấn đề liên quan