Haskell使用模式识别将列表拆分为子列表

时间:2015-05-04 20:53:19

标签: list haskell split sublist

我正在尝试拆分包含I和Os的数组,如果出现某种模式。

假设我有一个输入,看起来像这样:

data Bit = O | I  deriving (Eq, Show)    
let b = [I,I,O,O,O,O,O,I,I,O,O,O,I,O]

这就是我正在生成的,当编码[[Bool]] -> [Bit]相应的输入到我的编码函数时let a = [[True, False, False, True],[False, False],[False]]

现在我的目标是解码我生成的内容,所以我需要一个让我从b到a的函数。

但我不能想出一种方法将b列表分成3个子列表,每次它都读取I,O或I,I。每个奇数字母代表以下成员或起始数组成员。我基本上是在复制utf unicode编码。

所以我正在尝试构建一个能让我从b到a的函数。 过了一段时间我想出了这个:

split :: [Bit] -> [[Bit]]
split (x1:x2:xs) = if (x1 == I)
                    then [x2 : split xs]
                    else x2 : split xs

我无法弄清楚如何将列表拆分为子列表。任何建议/帮助/代码都非常感谢

编辑:

split :: [Bit] ->[[Bit]]
split [] = []
split xs = case foo xs of (ys,I,x2) -> -- generate new subarray like [...,[x2]]
                    (ys,O,x2) -> -- append existing subarray with value x2 [.....,[previous values]++x2]

foo :: [a] -> ([a],x1,x2)
foo x1:x2:input =  (input,x1,x2)

这两条评论是我需要弄清楚的最后一件事。在那之后我完成了:)

如果将b投放到函数split中,我想要此输出:[[I,O,O,I],[O,O],[O]] 最后一步是从b到[[True, False, False, True],[False, False],[False]]

2 个答案:

答案 0 :(得分:2)

我会从if (x1 == 1) ...

开始

如果x1Bit,可以是IO,为什么要将其平等与Num进行比较,{{1} }?

答案 1 :(得分:1)

如果我做对了,你需要这样的东西:

split [] = []
split xs = case foo xs of (ys,r) -> r : split ys

foo :: [a] -> ([a],r)
foo = undefined

foo中,列表应该被部分消耗,并返回列表的其余部分和要收集的值。

编辑:

data Bit = O | I deriving (Eq, Show)    

sampleA = [[True, False, False, True],[False, False],[False]]
sampleB = [I,I,O,O,O,O,O,I,I,O,O,O,I,O]

type TwoBit = (Bit,Bit)

twobit (x:y:xs) = (x,y) : twobit xs
twobit _ = []

split :: [TwoBit] -> [[Bool]]
split [] = []
split xs = case spli xs of (ys,r) -> r : split ys
    where
        spli :: [TwoBit] -> ([TwoBit],[Bool])
        spli (x:xs) = case span (not . pterm) xs of 
            (ys,zs) -> (zs, map ptrue $ x:ys)

        pterm x = (I,O) == x || (I,I) == x
        ptrue x = (O,I) == x || (I,I) == x

splitTB = split . twobit

main = print $ splitTB sampleB == sampleA

看起来像s -> (s,a)的PS函数也可以表示为状态monad。