Tôi đang cố gắng xây dựng một cấu trúc dữ liệu lười biếng chứa một bitmap vô hạn. Tôi muốn hỗ trợ các hoạt động sau đây:Bitmap lười biếng vô hạn
true :: InfBitMap
Trả về một bitmap vô hạn của True, ví dụ: tất cả các vị trí nên có giá trị True.
falsify :: InfBitMap -> [Int] -> InfBitMap
Đặt tất cả các vị trí trong danh sách để False. Danh sách này có thể là vô hạn. Ví dụ, falsify true [0,2 ..] sẽ trả về một danh sách trong đó tất cả (và chỉ) các vị trí lẻ là True.
check :: InfBitMap -> Int -> Bool
Kiểm tra giá trị của chỉ số.
Đây là những gì tôi có thể làm cho đến nay.
-- InfBitMap will look like [(@), (@, @), (@, @, @, @)..]
type InfBitMap = [Seq Bool]
true :: InfBitMap
true = iterate (\x -> x >< x) $ singleton True
-- O(L * log N) where N is the biggest index in the list checked for later
-- and L is the length of the index list. It is assumed that the list is
-- sorted and unique.
falsify :: InfBitMap -> [Int] -> InfBitMap
falsify ls is = map (falsify' is) ls
where
-- Update each sequence with all indices within its length
-- Basically composes a list of (update pos False) for all positions
-- within the length of the sequence and then applies it.
falsify' is l = foldl' (.) id
(map ((flip update) False)
(takeWhile (< length l) is))
$ l
-- O(log N) where N is the index.
check :: InfBitMap -> Int -> Bool
check ls i = index (fromJust $ find ((> i) . length) ls) i
tôi tự hỏi nếu có một số khái niệm Haskellish/cấu trúc dữ liệu mà tôi đang thiếu đó sẽ làm cho mã của tôi thanh lịch hơn/hiệu quả hơn (hằng số không quan trọng với tôi, chỉ cần theo thứ tự). Tôi đã cố gắng nhìn vào dây khóa kéo và ống kính nhưng họ dường như không giúp đỡ. Tôi muốn giữ sự phức tạp của các bản cập nhật và kiểm tra logarit (có lẽ chỉ là lôgarit phân bổ).
Lưu ý: trước khi ai đó nghi ngờ điều đó, đây không phải là vấn đề về bài tập về nhà!
Cập nhật:
Nó chỉ xảy ra với tôi kiểm tra có thể được cải thiện để:
-- O(log N) where N is the index.
-- Returns "collapsed" bitmap for later more efficient checks.
check :: InfBitMap -> Int -> (Bool, InfBitMap)
check ls i = (index l i, ls')
where
ls'@(l:_) = dropWhile ((<= i) . length) ls
Mà có thể được biến thành một đơn nguyên cho mã sạch sẽ.
Bạn có chắc chắn về 'InfBitMap' không? Nếu 'true' nên là đẳng cấu để' lặp lại True', 'InfBitMap' sẽ cần phải là một' [Bool] 'hoặc' Seq Bool', nhưng không phải cả hai. – Zeta
@ Zeta Tôi không có nghĩa là đúng là đẳng cấu để lặp lại True. Ý tôi là nó giữ một chuỗi vô hạn của True. Nếu nó là đẳng cấu để lặp lại True, điều đó sẽ làm cho tuyến tính kiểm tra ở N. – aelguindy
Tính phức tạp của 'falsify' dường như không đúng. Có 'L' cập nhật cho một chuỗi độ dài' N', là O (L * log N) rồi. –