Изучение Haskell: вопрос манипуляции со строками - PullRequest
5 голосов
/ 24 января 2010

Как я могу написать функцию на Haskell, которая принимает входную строку в формате a1a2a3 и расширяется до a1a2a2a3a3a3. Например, входная строка «code» будет расширена до «coodddeeee»

Ответы [ 5 ]

19 голосов
/ 24 января 2010

То есть вы хотите, чтобы символ nth повторялся n раза.

f :: String -> String
f x = concatMap g  (zip x [1..])
   where
       g (x,y) = replicate y x

Я уверен, что есть более простой способ сделать это.

Объяснение: Сначала мы получаем строку и соединяем ее с ее местом в списке (начиная с 1). Вот что делает zip:

Prelude> zip "code" [1..]
[('c',1),('o',2),('d',3),('e',4)]

Теперь функция g (x,y) использует функцию репликации, которая копирует все, что вы хотите y раз. Таким образом, мы повторяем x, y раз.

Prelude> g ('z',4)
"zzzz"

Если мы отобразим эту функцию поверх созданного списка, вы получите результат:

Prelude> map g $ zip "code" [1..]
["c","oo","ddd","eeee"]

Если у вас есть список строк, вы можете объединить их вместе, используя concat. concatMap применяет функцию g к каждой паре букв и цифр, а затем объединяет строку в окончательный результат.

Prelude> concat $ map g $ zip "code" [1..]
"coodddeeee"

В основном: concat $ map g -> concatMap g

РЕДАКТИРОВАТЬ: теперь это работает, это также может быть сделано в одну строку таким образом:

f x = concatMap (\(a,b)->replicate b a ) $ zip x [1..]

Выход:

Prelude> f "lambda"
"laammmbbbbdddddaaaaaa"
15 голосов
/ 25 января 2010
import Control.Monad
f = zip [1..] >=> uncurry replicate

выходы

Main> f "code"
"coodddeeee"
9 голосов
/ 24 января 2010

Наверное, очень неэффективно:)

f :: Int -> [Char] -> [Char]
f _ [] = []
f n (c:s) = (replicate n c) ++ (f (n+1) s)

g :: [Char] -> [Char]
g s = f 1 s

.

*Main> g "code"
"coodddeeee"
4 голосов
/ 01 сентября 2011

Почему люди ненавидят понимание списка?

Prelude> let f s = concat [ replicate x y | (x,y) <- zip [1..] s]
Prelude> f "code"
"coodddeeee"

или если вы хотите сходить с ума от расширений

Prelude> :set -XParallelListComp
Prelude> let f s = concat [ replicate x y | x <- [1..] | y <- s]
Prelude> f "code"
"coodddeeee"
1 голос
/ 31 августа 2011
Prelude> let l = "code" in concat $ [take y $ repeat (last $ take y l) | y <- [1..length l]]
"coodddeeee"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...