2013-10-09 38 views
1

我希望能够将字符串拆分为6个独立的字符串,每个字符。Haskell中的每个字符都分成6个部分的字符串

因此,例如IAMABADPROGRAMMER

会导致:IDA,APM,MRM,AOE,BGR,AR

有一个Haskell函数来做到这一点?

感谢

+0

所以你想要一个函数'字符串 - > [字符串]'组合每六个字符? – Inaimathi

+0

该字符串以6的倍数分隔。字符1转到字符串1,字符2转换为字符串2等,直到字符6转到字符串6,然后下一个字符7转回字符串1等等 – user2863323

回答

2

没有一个函数来做到这一点了,但它可以很容易地写:

import Data.List (transpose) 

chunk :: Int -> [a] -> [[a]] 
chunk _ [] = [] 
chunk n xs = first : chunk n rest where (first, rest) = splitAt n xs 

splitSkip :: Int -> [a] -> [[a]] 
splitSkip n xs = transpose $ chunk n xs 

main :: IO() 
main = print $ splitSkip 6 "IAMABADPROGRAMMER" 

我的第一直觉是它推广到所有列表,不只是名单Char s。当您记得类型[String][[Char]]相同时,您会看到最后会得到一个Char s的二维矩阵,如果您沿着从左到右的每列向下移动,则会返回原始列表。那么,这与转置矩阵并从上到下每行向下一样,这与将原始列表首先拆分为大块n元素相同。在这一点上,我有解决方案,只是后退。我写了一个快速函数来分块列表,然后使用Data.List中的transpose函数完成它。

+1

完美,谢谢 – user2863323

+3

另请参见'split'软件包(包含在Haskell平台中)的'chunksOf',允许您编写'splitSkip n = transpose。 chunksOf n'。 – Fixnum

+0

@ user2863323作为一项挑战,尝试实现自己的'splitAt'和'transpose'(不一定非常高效)。 'splitAt'非常容易,但是'transpose'应该是一个挑战(提示:'map','head','tail') – bheklilr

2

我相信这可能是与列表内涵并没有什么超出了基本的功能前奏做...

groupNth :: Int -> [a] -> [[a]] 
    groupNth n [] = [] 
    groupNth n xs = take n $ [ y | y <- everyNth xs ] : groupNth n (tail xs) 
      where 
      everyNth [] = [] 
      everyNth [email protected](y:ys) = y : everyNth (drop n l) 

似乎工作,我觉得是比使用转更有效。

+0

不是真正的效率更高,我把你的代码和我的一起运行它带有100万英镑('[1..1000000]')的'+ RTS -s -RTS',分成1000块,我的回答约为0.24秒,而你的运行时间约为4.6秒。这是一个20倍速差。 GC时间和最大记忆驻留大致相同,但我的堆空间使用量大约是其两倍。你可以在这里看到完整的输出 - > https://gist.github.com/bheklilr/6906826 – bheklilr

+1

啊,不能打败经验测试;-) – itsbruce

+0

你的评论只是让我好奇,哪个会更有效率,以及所以我让他们参加考试。我不认为我的速度会变慢,但在我之前我错了很多)=) – bheklilr

相关问题