2011-12-05 41 views
5

tôi đã viết mã này để tạo ra một danh sách từ en số lập luận choScheme: Xóa số trùng lặp từ danh sách

(define (create-list . e) 
    e) 

Nhưng tôi cần nó để loại bỏ bất kỳ số nhân đôi từ danh sách trong khối này chính nó.

Tôi đã thử và tìm kiếm hàng giờ và không thể tìm thấy giải pháp mà không đặt hàng tá dòng mã trên các khối khác.

Ví dụ giả sử đầu vào của tôi là

(create-list . 2 2 3 5 5) 

Tôi cần danh sách tạo ra để được '(2 3 5) và không' (2 2 3 5 5) ...

Trình tự số lượng không quan trọng.

+0

Xem thêm http://stackoverflow.com/a/8651932/450148 –

Trả lời

4

Về cơ bản, bạn cần phải làm điều gì đó như:

(define (create-list . e) (dedupe e)) 

tôi có thể nghĩ ra một cách thực sự đơn giản nhưng có lẽ không hiệu quả để làm điều này:

(define (dedupe e) 
    (if (null? e) '() 
     (cons (car e) (dedupe (filter (lambda (x) (not (equal? x (car e)))) 
            (cdr e)))))) 

Nếu bạn không thể sử dụng các chức năng hiện có như filter, bạn có thể tự tạo một mình:

(define (my-filter pred ls) 
    (cond ((null? ls) '()) 
     ((pred (car ls)) (cons (car ls) (my-filter pred (cdr ls)))) 
     (else (my-filter pred (cdr ls))))) 
+0

nó sẽ có thể để tạo ra các mã tương tự với cdr/xe/khuyết điểm và chỉ làm thủ tục nguyên thủy? (Không có bộ lọc/đầu/đuôi) – spacing

+0

Có. Trong thực tế, 'head' và' tail' đã chỉ là 'car' và' cdr' tương ứng (quá nhiều Haskell trong tâm trí của tôi). –

+0

Ngoài ra, lưu ý rằng cú pháp của tôi có thể hơi lệch - Tôi chỉ mới sử dụng Haskell gần đây và tôi chỉ sử dụng stk, một trình thông dịch lược đồ lỗi thời. –

0

Hiệu quả nhất (trave rsing danh sách một lần) cách để làm điều này là để xác định một chức năng mà đi qua danh sách yếu tố theo từng phần tử. Hàm lưu trữ một danh sách các phần tử nào đã có trong danh sách bị loại bỏ.

Lợi thế của giải pháp này trên @Tikhon Jelvis's, là các yếu tố danh sách không cần phải theo thứ tự, để được trùng lặp.

Với một hàm elem, mà nói nếu a là một phần tử của l:

(define (elem? a l) 
     (cond ((null? l) #f) 
      ((equal? a (car l)) #t) 
      (else (elem? a (cdr l))))) 

Chúng ta có thể đi qua danh sách, lưu trữ mỗi phần tử chúng ta chưa từng thấy trước đây:

(define (de_dupe l_remaining already_contains) 
    (cond ((null? l_remaining) already_contains) 
     ((elem? (car l_remaining) already_contains) (de_dupe (cdr l_remaining) already_contains)) 
     (else (de_dupe (cdr l_remaining) (cons (car l_remaining) already_contains))))) 

Note : cho hiệu quả, điều này trả về các phần tử theo thứ tự ngược lại

+1

Phiên bản của tôi có cần các yếu tố theo bất kỳ thứ tự nào không? Theo như tôi biết, nó không. –

+0

@Tikhon Jelvis: Trông giống như vậy; Tôi không thể làm cho nó trở lại những giá trị thích hợp. Ví dụ: "(tạo danh sách 3 5 4 3 4 6)" trả về "(3 3)" – amindfv

+0

Đó không phải vì thứ tự, đó là vì tôi vô tình bỏ sót một không trong vị từ của bộ lọc. Tôi đã sửa nó ngay bây giờ. –

2

Cái này nhanh hơn:

(define (remove-duplicates l) 
    (cond ((null? l) 
     '()) 
     ((member (car l) (cdr l)) 
     (remove-duplicates (cdr l))) 
     (else 
     (cons (car l) (remove-duplicates (cdr l)))))) 

Nhưng tốt hơn nữa, mit-scheme cung cấp các bản sao xóa, thực hiện chính xác những gì bạn muốn.

0
(define (delete x) 
(cond 
((null? x) x) 
((= (length x) 1) x) | ((null? (cdr x)) x) 
((= (car x) (cadr x)) (delete (cdr x))) 
(#t (cons (car x) (delete (cdr x)))) 
) 
) 
Các vấn đề liên quan