4
下面的函數search
搜索兩個在某些函數下具有相同輸出的輸入。在搜索期間,它重複輸入列表xs
兩次,並且這個輸入列表可能非常大,例如, [0..1000000000]
。我寧願使用內存來存儲由碰撞創建的HashSet,而不是存儲xs
的元素,我的理解是,儘管xs
可能會被延遲計算,但它將保留在需要調用find
的情況下。強制重新列表重新計算
問題:
- 是這樣理解是否正確?
- 如果我把它作爲一個列表有沒有一種方法,我可以
xs
重新計算,如果它傳遞給find
? - 是否有替代的數據結構我可以用於
xs
,它允許我控制使用的空間?xs
僅用於指定要檢查的輸入。
請注意,xs
沒有類型限制 - 它可以是任何類型的集合。
import Data.HashSet as Set
import Data.Hashable
import Data.List
search :: (Hashable b, Eq b) => (a->b) -> [a] -> Maybe (a,a)
search h xs =
do x0 <- collision h xs
let h0 = h x0
x1 <- find (\x -> (h x) == h0) xs
return (x0,x1)
collision :: (Hashable b, Eq b) => (a->b) -> [a] -> Maybe a
collision h xs = go Set.empty xs
where
go s [] = Nothing
go s (x:xs) =
if y `Set.member` s
then Just x
else go (Set.insert y s) xs
where y = h x
main = print $ search (\x -> x `mod` 21) ([10,20..2100] :: [Int])
你真的是指''x1 < - find(\ x - >(h x)'Set.member' s)xs''而不是'h x == h0'? –
很好的捕捉 - 這簡單很多 – ErikR
您可以在[美麗摺疊](http://squing.blogspot.com/2008/11/beautiful-folding.html)中調整想法以產生漂亮的掃描效果。 –