2014-12-22 2 views
0

Как я могу сделать здесь фильтр (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))) для списка Преобразовать в строку.

+0

Значение '' '' не имеет значения Char. Таким образом, вам, по крайней мере, понадобится '[('a', '0'), ('b', '2')]' или '[('a', 0), ('b', 2)]' – tokosh

+0

@tokosh спасибо, обновленный вопрос. – rel1x

ответ

2

Как я новичок сам, это, вероятно, не очень haskellian. Но вы можете сделать это примерно так (хз, как бы список [('a', 1), ('b', 2), ('a', 3)]):

Создать "a1b2a3":

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

Фильтр из 1s:

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

даст вам «ab2a3 "

+1

или, объедините оба 'concat $ map (\ (c, l) -> c: (if l == 1 then" "else show l))' – karakfa

+0

@karakfa благодарю вас. Ваш ответ лучше, потому что с алгоритмом tokosh, если у меня есть '' aaaaaaaaaaaa, '' результат 'a2'. – rel1x

1

Вы не можете иметь список, как это в Haskell:

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

Каждый элемент, если список должен иметь тот же тип в Haskell, и («с») [(«а»): : Char] и ('b', 3) [('a', 1) :: Num t => (Char, t)] - разные типы.

Может также взглянуть на List of different types?

Я хотел бы предложить, что вы изменили свой список на Char (структура данных, Может быть, NUM).

Edit:

Ваш новый вопрос, я думаю, что вы искали это:

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 
+0

О, извините, я ошибся, я обновил свой вопрос – rel1x

+0

'num' не тип, даже' char' – Shoe

+0

Хм, да, вы правы. Я ссылался на то, что: t ('a', 1) возвращает ('a', 1) :: Num t => (Char, t). Не хотел доводить это до конца. Я обновлю его. – quant

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)     
Смежные вопросы