按长度过滤

时间:2014-12-22 18:16:59

标签: haskell

我如何在此处过滤(x:xs) = (x, length (x:xs)),其长度为> 1?

目前,如果输入为abcaaabbb,则输出为[('a',1),('b',1),('c',1),('a',3),('b',3)],但我正在寻找abca3b3

我的代码:

import Data.List

encode :: [Char] -> [(Char, Int)]
encode s = map go (group s)
               where go (x:xs) = (x, length (x:xs))

main = do
    s <- getLine
    print (encode s) 

最后一个字符串将putStrLn (concat (map (\(x,y) -> x : [y]) (encode s)))用于将列表转换为字符串。

3 个答案:

答案 0 :(得分:2)

由于我自己是新手,这可能不是非常哈克利。但是你可以这样做(xs就像列表[('a', 1), ('b', 2), ('a', 3)]):

创建“a1b2a3”:

concat $ map (\(c, l) -> c:(show l)) xs

过滤掉1s:

filter (\x -> x /= '1') "a1b2a3"

会给你“ab2a3”

答案 1 :(得分:1)

你不能在Haskell中有这样的列表:

[('a'),('b'),('c'),('a',3),('b',3)]

每个元素如果列表需要在haskell中具有相同的类型,并且('c')[('a'):: Char]和('b',3)[('a',1): :Num t =&gt; (Char,t)]是不同的类型。

也许还要看看List of different types?

我建议您将列表更改为(Char,Maybe num)数据结构。

修改

从你的新问题来看,我认为你一直在寻找:

import Data.List

encode :: [Char] -> [(Char, Int)]
encode s = map go (group s)
               where go (x:xs) = (x, length (x:xs))

f :: (Char, Int) -> String
f (a, b) = if b == 1 then [a] else [a] ++ show b

encode2 :: [(Char, Int)] -> String
encode2 [] = []
encode2 (x:xs) = f(x) ++ encode2 xs

main = do
    s <- getLine
    putStrLn $ encode2 $ encode s

答案 2 :(得分:0)

不确定这是否符合您的需求,但如果您不需要过滤,则可以完成以下工作:

encode::String -> String
encode "" = ""
encode (x:xs) = doIt0 xs x 1 where
        doIt0 [] ch currentPos = [ch]++showPos currentPos
        doIt0 (x:xs) ch currentPos
                |x==ch = doIt0 xs ch $ currentPos+1
                |otherwise= [ch]++ (showPos currentPos) ++ (doIt0 xs x 1)
        showPos pos = if pos> 1 then show pos else ""

main = do
        s <- getLine
        print (encode s)