簡體   English   中英

如何在Haskell中找到列表中最長的數字增長部分?

[英]How can I find the longest increasing section of numbers at list in Haskell?

例如,列表[1,3,4,3,6,7,3]給出結果[1,3,4][3,6,7] 我只能找到后續但不是一節。

編輯

通過Naive實現,我發現后續

increasing :: Ord a => [a] -> [a]
increasing = maximumBy (comparing length) . map nub 
                                          . filter isSorted
                                          . subsequences

二進制謂詞切割序列; 切割發生在x1 <> x2不成立的第一對(x1, x2)

biCut :: (a -> a -> Bool) -> [a] -> ([a], [a])
biCut (<>) (x1 : xs@(x2 : _)) | x1 <> x2  = let (tk, dp) = biCut (<>) xs
                                            in  (x1 : tk, dp)
                              | otherwise = ([x1], xs)
biCut _    xs                             = (xs, [])

(類似於splitAt )或者就類似而言

biFst :: (a -> a -> Bool) -> [a] -> [a]
biFst (<>) (x1 : xs@(x2 : _)) | x1 <> x2  = x1 : biFst (<>) xs
                              | otherwise = [x1]
biFst _    xs                             = xs

biSnd :: (a -> a -> Bool) -> [a] -> [a]
biSnd (<>) (x1 : xs@(x2 : _)) | x1 <> x2  = biSnd (<>) xs
                              | otherwise = xs
biSnd _    _                              = []

takedrop ),使得forall (<>) xs.

biFst (<>) xs ++ biSnd (<>) xs  =  xs
                 biCut (<>) xs  =  (biFst (<>) xs, biSnd (<>) xs)    [CUT]

然后

sections :: (a -> a -> Bool) -> [a] -> [[a]]
sections _    [] = []
sections (<>) xs = let (tk, dp) = biCut (<>) xs
                   in  tk : sections (<>) dp

這樣的

        concat . sections (<>)  =  id

“Sections”是非空子序列,二進制謂詞<>在后繼者之間保持。 重新制定標准maximumBy作為總函數

maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> Maybe a
maximumBy cmp xs | null xs   = Nothing
                 | otherwise = Just (foldl1 max' xs)
   where
      max' x y = case x `cmp` y of
                    LT -> y            -- Leftmost-biased
                    _  -> x

然后

longestAsc :: Ord a => [a] -> Maybe [a]
longestAsc = maximumBy (compare `on` length) . sections (<)

是功能。

      longestAsc [2,3,2,1,2,3]  =  Just [1,2,3]
              longestAsc [2,1]  =  Just [2]
                 longestAsc []  =  Nothing

看來你的方式很好 - 而且你似乎已經了解了很多 - 所以我不會為你破壞結果。

起初我認為你應該改變你的功能的類型簽名

increasingSequences :: Ord a => [a] -> [[a]]

已經有一個函數可以解決這個問題來自Data.ListgroupBy ,以groupBy (<=)的形式。

但是groupBy沒有按預期工作,它與每個組的第一個元素進行比較 - 這對於groupBy (==) - 但不適用於你的情況。

> ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/epsilonhalbe/.ghc/ghci.conf
Prelude> import Data.List
Prelude Data.List> groupBy (<=) [10,9..6]
[[10],[9],[8],[7],[6]]
Prelude Data.List> groupBy (<=) (1:[10,9..6])
[[1,10,9,8,7,6]]

所以你需要自己實現一個 - 最簡單的版本恕我直言將使用模式匹配和遞歸 - 我強烈建議寫它並在這里作為答案發布(我將在接下來的幾天檢查並投票,如果你做!)

如果你真的想要一個劇透,那么實際上有一個wiki頁面可以解決你的問題。

groupBy :: (a -> a -> Bool) -> [a] -> [[a]] groupBy rel [] = [] groupBy rel (x:xs) = (x:ys) : groupBy rel zs where (ys,zs) = groupByAux x xs groupByAux x0 (x:xs) | rel x0 x = (x:ys, zs) where (ys,zs) = groupByAux x xs groupByAux y xs = ([], xs)

暫無
暫無

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

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