Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 分段Haskell列表_List_Haskell - Fatal编程技术网

List 分段Haskell列表

List 分段Haskell列表,list,haskell,List,Haskell,给定haskell中的一个排序列表,如何获得连续数字放在同一个列表中的分段列表。例如,如果我有一个排序列表[1,2,3,4,7,8,10,12,13,15],结果将是[[1,2,3,4],[7,8],[10],[12,13],[15],此函数可以提供帮助 addFirstInRun::Int->[Int]->[(Int, Int)] addFirstInRun _ [] = [] addFirstInRun lowVal (x:y:rest) | y - x > 1 = (lo

给定haskell中的一个排序列表,如何获得连续数字放在同一个列表中的分段列表。例如,如果我有一个排序列表
[1,2,3,4,7,8,10,12,13,15]
,结果将是
[[1,2,3,4],[7,8],[10],[12,13],[15]
,此函数可以提供帮助

addFirstInRun::Int->[Int]->[(Int, Int)]
addFirstInRun _ [] = []
addFirstInRun lowVal (x:y:rest) | y - x > 1 = (lowVal, x):firstInRun y (y:rest)
addFirstInRun lowVal (x:rest) = (lowVal, x):firstInRun lowVal rest
它将列表中的每个值与另一个数字(当前箱子的“头”)配对

> addFirstInRun 1 [1,2,3,5,6,7,10]

  [(1,1),(1,2),(1,3),(5,5),(5,6),(5,7),(10,10)]
(很抱歉,您需要手动放入第一个……您可以编写一个方便的包装来修复此问题)

使用此选项,您可以使用
groupBy

groupBy ((==) `on` fst)
你可以用这个来清理最后的答案

map (map snd)
把这些放在一起

> map (map snd) $ groupBy ((==) `on` fst) $ addFirstInRun 1 [1,2,3,5,6,7,10]

  [[1,2,3],[5,6,7],[10]]

(您需要导入
数据.Function
数据.List

解决方案的概要:

1-将每个元素与下一个元素配对:

(1,2) (2,3) (3,4) (4,7) (7,8) (8,10) (10,12) (12,13) (13,15) ...
2-检查每对是否连续:

(1,2) (2,3) (3,4) (4,7) (7,8) (8,10) (10,12) (12,13) (13,15) ...
True  True  True  False True  False  False   True    False   ...
3-在
False
值处分解列表:

(1,2) (2,3) (3,4) (4,7) | (7,8) (8,10) | (10,12) | (12,13) (13,15) | ...
True  True  True  False | True  False  | False   | True    False   | ...
4-对于每个段,取成对的
fst

1 2 3 4 | 7 8 | 10 | 12 13
这只是一个折页:

q :: (Enum a, Eq a) => [a] -> [[a]]
q = foldr foo []
  where
    foo x (ys@(y:_) : zzs) | succ x == y = (x:ys) : zzs
    foo x t = [x] : t
*Main>q[1,2,3,4,7,8,10,12,13,15]

[1,2,3,4]、[7,8]、[10]、[12,13]、[15]]

更新:也可以将其转换为foldl,在这里我使用“差异列表”来实现:

type N a = Maybe ( [[a]] -> [[a]], [a] -> [a], a )

p :: (Enum a, Eq a) => [a] -> [[a]]
p = close . foldl bar Nothing
  where
    close :: N a -> [[a]]
    close Nothing = []
    close (Just (f, g, _)) = (f  . (g []:)) []

    bar :: (Enum a, Eq a) => N a -> a -> N a
    bar Nothing x = Just (id, (x:), x)
    bar (Just (f, g, y)) x | succ y == x = Just (f, g . (x:), x)
                           | otherwise = Just ( f . (g []:), (x:), x)
更新2:“f”是一个在无限列表上安全的变体:

f :: (Enum a, Eq a) => [a] -> [[a]]
f [] = []
f (x:xs) = go x xs
  where
    go x xs = let (run, rest) = getRun x xs
              in run : f rest
    getRun x t@(y:ys) | succ x == y = let (run, rest) = getRun y ys
                                      in (x:run, rest)
    getRun x t = (x:[], t)
或较短的“f”:

f :: (Enum a, Eq a) => [a] -> [[a]]
f [] = []
f (x:xs) = getRun x xs
  where
    getRun x t@(y:ys) | succ x == y = let (run : rest) = getRun y ys
                                      in (x:run) : rest
    getRun x t = (x:[]) : f t

t3 = [1,2,3,10,11,12] ++ [15..]
*干道>第三道(地图(第五道)(t3层))

[1,2,3]、[10,11,12]、[15,16,17,18,19]]


也许你可以让
groupBy
做一些有用的事情?是的,但不太确定如何使用它。我试过groupBy(\x y->x-y==1)[1,2,3,4,7,8,10,12,13,15]它给了我错误!尝试导入数据。列出你的groupBy表达式错误是x和y不在范围内。无论如何,groupBy在这种情况下不起作用,它根据连续元素测试组中的第一个元素,而不是根据下一个元素测试最后一个匹配。e、 g.它将测试
(1,2)、(1,3)
而不是
(1,2)、(2,3)