我正在嘗試爲其中一個Hackerrank問題編寫解決方案。面臨的挑戰是對列表中的元素進行計數,元素從0到99不等,因此可以用線性時間對它們進行計數。這是我得到的:快速統計列表中的已知元素
{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_GHC -O3 #-}
module Main where
import Data.STRef
import Data.Foldable
import Control.Monad
import Control.Monad.ST
main = do
line1 <- getLine
line2 <- getLine
let
!ns = map read $ words line2 :: [Int]
res = runST $ do
refs <- forM [0..99] $ \i ->
newSTRef (0 :: Int)
traverse_ (\x -> modifySTRef' (refs !! x) (+1)) ns
mapM (\ref -> readSTRef ref) refs
putStrLn . unwords . map show $ res
此代碼的工作原理,但不夠快,通過最後一個測試用例。有人可以推薦改進嗎? (link to the problem)
我試圖使用MVectors。它確實將我其他測試案例的時間提高了30%,但仍然不夠快。 –
它工作。我只是使用未分析的字符串作爲Map鍵,如「0」「1」..「99」。它使整件事運行速度提高了7倍。 –
哦,我甚至沒有想到!字符串幾乎總是會成爲瓶頸。如果你想快速解析,看看'attringarsec' over'bytestring'。 –