如何解决在Haskell中解析大型矩阵
我最近开始学习Haskell,正在测试我使用Google KickStart代码挑战学到的东西。
我正在查看的problem本质上要求从标准输入中读取平方矩阵,并对与主对角线平行的对角线上的元素求和。 我编写了一个简单的程序来解决该问题,该程序通过了第一个测试,但未通过第二个测试。 问题似乎是第二个测试中的输入比第一个测试大得多,并且我编写的解析器太慢或使用了太多内存。
输入被格式化为一系列矩阵
n
a11 ... a1n
...
an1 ... ann
我第一次尝试使用内置函数
type Matrix = [[Int]]
parseInput:: String -> [Matrix]
parseInput = parseInput' . lines
where
parseInput':: [String] -> [Matrix]
parseInput' [] = []
parseInput' (i:is) = let (m,rest) = splitAt (read i) is in
(map ((map read).words) m) : (parseInput' rest)
main = do
input <- getContents
let result = show $ parseInput input
putStr result
第二次尝试使用parsec库
import Text.Parsec
import Text.Parsec.String (Parser)
type Row = [Int]
type Matrix = [[Int]]
matrixSize::(Integral a,Read a) => Parser a
matrixSize = do
n <- ( many1 digit ) <* newline
return $ read n
matrixRow:: Parser Row
matrixRow = do
row <- (sepBy1 (many1 digit) (char ' ')) <* (newline <|> (eof >> return ' '))
return $ map read row
parseMatrix:: Parser Matrix
parseMatrix = do
n <- matrixSize
mat <- count n matrixRow
return mat
parseInput:: Parser [Matrix]
parseInput = (many1 parseMatrix)
prepareInput:: String -> [Matrix]
prepareInput input = case parse parseInput "" input of
Right l -> l
Left _ -> []
main = do
input <- getContents
let result = show $ prepareInput input
putStr result
根据Google网站,第二个测试实例最多包含100个矩阵,其中10个的大小最大为1000,元素的大小最大为10 ^ 7,其余的矩阵的大小最大为100。
我生成了一个random test file,其中包含10个大型矩阵,大小最多为1000,结果大约是30MB。 在测试文件上运行任何一个解析器在我的计算机上大约需要13s,第二个使用超过1GB的内存。 两者都无法满足在服务器上运行的要求:第一个超过20秒的执行时间,第二个则超过1GB的内存限制。
是否有更好的解析大文件的方法? 在我的代码中是否可以解决任何效率低下的问题?
任何建议将不胜感激!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。