簡體   English   中英

Haskell IO:從樹中刪除隨機元素

[英]Haskell IO: remove a random element from a tree

考慮以下類型來表示樹:

data Tree a = Empty
            | Leaf a
            | Fork (Tree a) (Tree a)

我需要幫助來定義功能removeRandom' :: Tree a -> IO (Tree a) ,該函數接收至少具有葉子的樹,並返回從樹中刪除隨機葉子的結果(將其替換為Empty)。 該練習提出了一個建議:使用函數randomRIO :: Random a => (a,a) -> IO a生成要刪除的元素的順序

編輯:嘗試用戶Thomas的方法2

removeRandom' :: Tree a -> IO (Tree a)
removeRandom' t = let lengthTree = numbelems t
                  in do x <- randomRIO (0,lengthTree -1)
                        return (remove x t)

numbelems :: Tree a -> Int
numbelems Empty = 0
numbelems Leaf x = 1
numbelems Fork l r = (numbelems l) + (numbelems r)

remove :: Int -> Tree a -> Tree a
remove _ (Leaf x) = Empty
remove n (Fork l r) = let lengthLeft = numbelems l
                      in if (n>lengthLeft) then Fork l (remove (n-lengthLeft r)
                         else Fork (remove n l) r

有兩種方法可以解決此問題

  1. 轉換為列表,刪除元素,然后轉換回樹。

    • 優點 :易於實現,您已經擁有toList,您只需要fromList,並且可以簡單地實現解決方案

       removeAt :: Int -> [a] -> [a] removeAt n as = a ++ tail s where (a, s) = splitAt n removeRandom' tree = do element <- randomRIO (0, length tree) return $ fromList $ removeAt element $ toList tree 
    • 缺點 :對於removing a random leaf from the tree (replacing it with Empty)的問題陳述,此方法不是“正確的”,並且可能會給您提供一個沒有Empty值的全新樹。 我只是將此作為選項提供,試圖顯示您的toList方法在哪里結束。

  2. 下降到樹中,直到找到要刪除的元素,然后在備份的方向上重建樹

    • 優點 :算法的實質是“純”的,不接觸IO removeRandom'內,您實際上實際上只需要IO片刻。 您可能會寫一個看起來像這樣的解決方案(有趣的部分留空;)。

       removeAt :: Int -> Tree a -> Tree a removeAt n tree = walk 0 tree where walk i Empty = ... walk i (Fork lr) = ... walk il@(Leaf _) | i == n = ... | otherwise = ... removeRandom' tree = do element <- randomRIO (0, length tree) return $ removeAt element tree 
    • 缺點 :實施起來比較復雜,您需要知道如何向后“向上”移動一棵樹,並在重建后進行重建,還需要知道如何使用累加器編寫一個遞歸函數,以便可以跟蹤在樹中的位置。樹。

無論您采用哪種方式,都需要編寫一個函數length :: Tree a -> Int randomRIO length :: Tree a -> Int ,該函數計算要用作randomRIO輸入的葉數(這是一個在給定范圍內簡單產生隨機值的動作) 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM