在整数列表中搜索,这是按增长排序的最长有序子集之一(不一定是连续的)

时间:2017-11-26 10:11:08

标签: haskell functional-programming

函数,它在整数列表中找到下标的最长有序增量之一(不一定是连续的)数字。例如:

•序列[21,27,15,14,18,16,14,17,22,13] = [14,16,17,22]

我的函数有一个问题,它从数组中获取初始数,并查找序列:

fstLen:: Int -> [Int] -> [Int]    
fstLen a [] = a: []    
fstLen x (l:ls) = if x < l then x:(fstLen l ls) else fstLen x ls

我遇到了问题,14,18,16,14,17,22,13 14&lt; 18然后18> 16,我的算法以数字16为基础,正在寻找新的序列,我需要回到14 我该怎么办?

(对不起我的英文)

2 个答案:

答案 0 :(得分:3)

您可以随时使用subsequences中的Data.List来获取列表中所有可能的子序列。当您获得这些子序列时,只需使用此函数和filter

进行排序
isSorted :: (Ord a) => [a] -> Bool
isSorted [] = True
isSorted [_] = True
isSorted(x:y:xs) = x <= y && isSorted (y:xs)

然后使用maximumBy(或其他方法)获取最大长度子序列,排序为comparing length

这是代码的样子:

import Data.Ord (comparing)
import Data.List (subsequences, maximumBy, nub)

isSorted :: (Ord a) => [a] -> Bool
isSorted [] = True
isSorted [_] = True
isSorted(x:y:xs) = x <= y && isSorted (y:xs)

max_sequence :: (Ord a) => [a] -> [a]
max_sequence xs = maximumBy (comparing length) $ map nub $ filter isSorted (subsequences xs)

这似乎工作正常:

*Main> max_sequence [21,27,15,14,18,16,14,17,22,13]
[14,16,17,22]

注意:使用map nub从子序列中删除重复的元素。如果没有使用,那么这将返回[14,14,17,22]作为最大子序列,如果允许,这可能没问题。

答案 1 :(得分:3)

通过维护地图

,可以实现更高效的n log n解决方案
  • 键是增加序列的第一个元素。
  • 值是一个元组:(序列的长度,实际序列)

并且地图保持对于递增序列的每个可能大小的不变性,仅保留按字典顺序排列的最大序列

额外traceShow以显示从列表末尾折叠时地图如何变化:

import Debug.Trace (traceShow)
import Data.Map (empty, elems, insert, delete, lookupGT, lookupLT)

-- longest (strictly) increasing sequence
lis :: (Ord k, Show k, Foldable t) => t k -> [k]
lis = snd . maximum . elems . foldr go empty
  where
  go x m = traceShow m $ case x `lookupLT` m of
    Nothing -> m'
    Just (k, v) -> if fst a < fst v then m' else k `delete` m'
    where
    a = case x `lookupGT` m of
      Nothing -> (1, [x])
      Just (_, (i, r)) -> (i + 1, x:r)
    m' = insert x a m

然后:

\> lis [21,27,15,14,18,16,14,17,22,13]
fromList []
fromList [(13,(1,[13]))]
fromList [(22,(1,[22]))]
fromList [(17,(2,[17,22])),(22,(1,[22]))]
fromList [(14,(3,[14,17,22])),(17,(2,[17,22])),(22,(1,[22]))]
fromList [(16,(3,[16,17,22])),(17,(2,[17,22])),(22,(1,[22]))]
fromList [(16,(3,[16,17,22])),(18,(2,[18,22])),(22,(1,[22]))]
fromList [(14,(4,[14,16,17,22])),(16,(3,[16,17,22])),(18,(2,[18,22])),(22,(1,[22]))]
fromList [(15,(4,[15,16,17,22])),(16,(3,[16,17,22])),(18,(2,[18,22])),(22,(1,[22]))]
fromList [(15,(4,[15,16,17,22])),(16,(3,[16,17,22])),(18,(2,[18,22])),(27,(1,[27]))]
[15,16,17,22]

没有必要在地图中保留列表。可以仅使用密钥和序列的长度(即,仅元组的第一元素)来重建最长的增加序列。