我正在尝试拆分包含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]]
答案 0 :(得分:2)
我会从if (x1 == 1) ...
如果x1
是Bit
,可以是I
或O
,为什么要将其平等与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。