2011-12-12 44 views
10

Tôi đang cố gắng viết một hàm haskell có hai danh sách các số nguyên và tạo một danh sách với các phần tử được chọn luân phiên từ hai danh sách.Haskell - các phần tử xen kẽ từ hai danh sách

tôi có chức năng:

blend xs ys 

Một ví dụ:

blend [1,2,3] [4,5,6] 

nên trở

[1,4,2,5,3,6] 

logic của tôi là để zip hai danh sách với nhau, tạo ra các cặp thay thế các yếu tố, sau đó bằng cách nào đó loại bỏ chúng khỏi bộ dữ liệu của chúng.

Việc xóa chúng khỏi bộ dữ liệu của chúng mà tôi không thể tìm ra cách triển khai.

Trả lời

18

Làm thế nào để trao đổi các đối số trong quá trình đệ quy-xuống?

blend (x:xs) ys = x:(blend ys xs) 
blend _ _ = [] 

Bạn thậm chí có thể khái quát phương pháp này cho bất kỳ số lượng danh sách (Tôi sẽ rời khỏi đây với bạn) hoặc đưa các yếu tố còn lại của danh sách nếu khác rỗng:

blend _ ys = ys 
+0

Cách rất hay để làm điều đó! Cảm ơn. – Shabu

6

tôi sẽ giả định rằng đây là bài tập về nhà. Với điều kiện là bạn có thể tạo danh sách sau đây (như bạn nói):

[(1,4),(2,5),(3,6)] 

... bạn có thể giải quyết nó với 2 chức năng:

  1. Bạn cần phải chuyển đổi một tuple (a, b) vào một danh sách [a, b]. Hãy thử sử dụng mẫu phù hợp! Chức năng này cần phải được áp dụng (aka. Ánh xạ) trên tất cả các yếu tố của danh sách bạn có.
  2. Bạn sẽ có danh sách các danh sách, như [[1,4],[2,5],[3,6]], vì vậy bạn cần có một chức năng để nối các danh sách con vào một danh sách lớn.

Có tất nhiên, có thể cao hơn, cách để giải quyết vấn đề này, nhưng bạn nên tiếp tục với cách tiếp cận ban đầu của mình.

+1

Tôi nghĩ rằng câu trả lời cho câu hỏi 'bài tập về nhà 'tiếp tục theo hướng ban đầu đặc biệt hữu ích (trừ khi hướng hoàn toàn sai, trong trường hợp này, không phải). –

4

Nếu bạn muốn nén, tạo danh sách thay vì các bộ:

concat $ zipWith (\x y -> [x,y]) [1,2,3] [4,5,6] 

Một số vui vẻ vô nghĩa:

concat $ zipWith ((flip(:)).(:[])) [1,2,3] [4,5,6] 

Có lẽ cách dễ nhất:

import Data.List 
concat $ transpose [[1,2,3],[4,5,6]] 
2

Một giải pháp mà không sử dụng concat hoặc đệ quy rõ ràng:

blend l = foldr($)[] . zipWith(.) (map(:)l) . map(:) 

Chúng ta có thể thực hiện cũng làm cho này điểm miễn

blend' = (foldr($)[].) . (.map(:)) . zipWith(.) . map(:) 


Cách hoạt động: đầu tiên trang trí cả hai danh sách với các nhà khai thác nhược điểm

\[1,2,3] [4,5,6] -> [1:, 2:, 3:] [4:, 5:, 6:] 

thì chúng ta nén này cùng với hàm hợp

-> [(1:).(4:), (2:).(5:), (3:).(6:)] 

và cuối cùng gấp lại ứng dụng của tất cả các tác phẩm này từ bên phải sang danh sách trống

-> (1:).(4:) $ (2:).(5:) $ (3:).(6:) $ [] = 1:4:2:5:3:6:[] = [1,4,2,5,3,6] 
+0

Có vấn đề gì với điều này? – leftaroundabout

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