您必須使用遞回來定義 rmax2,并且必須從“頭”開始。也就是說,除了 cons 運算子、head、tail 和比較之外,您不應使用 Haskell 庫中的任何函式。
我創建了一個函式,使用串列理解洗掉最大專案的所有實體。如何使用遞回洗掉最大數字的最后一個實體?
ved :: Ord a => [a] -> [a]
ved [] =[]
ved as = [ a | a <- as, m /= a ]
where m= maximum as
uj5u.com熱心網友回復:
如果您嚴格要求使用遞回,則可以使用 2 個輔助函式:一個用于反轉串列,第二個用于在反轉反轉串列時洗掉第一個最大的。
這會生成一個串列,其中洗掉了最后一次出現的最大元素。
我們還使用布爾標志來確保我們不會洗掉多個元素。
這是丑陋的代碼,我真的不喜歡它。一種使事情更清晰的方法是將串列的反轉移動到當前函式之外的輔助函式,以便主函式只有一個輔助函式。另一種方法是使用內置reverse函式并僅在洗掉時使用遞回。
removeLastLargest :: Ord a => [a] -> [a]
removeLastLargest xs = go (maximum xs) [] xs where
go n xs [] = go' n True [] xs
go n xs (y:ys) = go n (y:xs) ys
go' n f xs [] = xs
go' n f xs (y:ys)
| f && y == n = go' n False xs ys
| otherwise = go' n f (y:xs) ys
uj5u.com熱心網友回復:
借用Hackage中 dropWhileEnd的實作,我們可以實作一個輔助函式splitWhileEnd:
splitWhileEnd :: (a -> Bool) -> [a] -> ([a], [a])
splitWhileEnd p = foldr (\x (xs, ys) -> if p x && null xs then ([], x:ys) else (x:xs, ys)) ([],[])
splitWhileEnd根據最后的預測器拆分串列。例如:
ghci> xs = [1,2,3,4,3,2,4,3,2]
ghci> splitWhileEnd (< maximum xs) xs
([1,2,3,4,3,2,4],[3,2])
使用這個輔助函式,你可以寫成ven:
ven :: Ord a => [a] -> [a]
ven xs =
let (x, y) = splitWhileEnd (< maximum xs) xs
in init x y
ghci> ven xs
[1,2,3,4,3,2,3,2]
對于您的情況,您可以重構splitWhileEnd為:
fun p = \x (xs, ys) -> if p x && null xs then ([], x:ys) else (x:xs, ys)
splitWhileEnd' p [] = ([], [])
splitWhileEnd' p (x : xs) = fun p x (splitWhileEnd' p xs)
ven' xs = let (x, y) = splitWhileEnd' (< maximum xs) xs in init x y
如果init與 不準,你可以手動執行。這很簡單!
順便說一句,我想這可能是你的 Haskell 課程作業。如果你的老師給出限制,我認為這很荒謬。現在誰在從頭開始編程?
無論如何,您始終可以通過手動重新實作內置函式來解決這種限制。祝你好運!
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316800.html
標籤:哈斯克尔
