我尝试使用数组实现计数排序。
输入:count_of_elements" \ n" (array_element""){n}
所有array_element都在[1..10]
中我写了以下代码:
import Data.Array
import Data.List
toIntLst :: String -> [Int]
toIntLst = map read . words
main = do
getLine
y <- getLine
let nums = toIntLst y
let arr = array(1,10) [(i, 0) | i <- [1..10]]
let sum_arr = foldl (\acc x -> arr//[(x, (arr ! x) + 1)]) arr nums
let result = concat $ map (\x -> replicate (sum_arr ! x) x) $ indices sum_arr
print nums
print sum_arr
print result
我误解了为什么将名字折叠到sum_arr的结果不符合我的期望(我预计该数组将包含所有元素的出现)。得到的数组等于一个数组,可以通过删除除nums的最后元素之外的所有数据然后进行相同的折叠来获得。
P.S。你能告诉我Haskell的阵列访问时间是否为O(1)?我在这里找不到这些信息:http://hackage.haskell.org/package/array-0.5.0.0/docs/Data-Array.html和不寻常的数组接口使我感到困惑。
答案 0 :(得分:4)
使用-Wall
进行编译,然后您会看到问题:
runhaskell -Wall /tmp/wtmpf-file15704.hs
/tmp/wtmpf-file15704.hs:2:1:警告:
“Data.List”的导入是多余的 除了从'Data.List'中导入实例外 要单独导入实例,请使用:import Data.List()
/tmp/wtmpf-file15704.hs:7:1:警告:
没有类型签名的顶级绑定:main :: IO()
/tmp/wtmpf-file15704.hs:8:3:警告:
一个do-notation语句丢弃了String类型的结果 通过说“_&lt; - getLine”,
来抑制此警告 或者使用标志-fno-warn-unused-do-bind
/tmp/wtmpf-file15704.hs:12:25:警告:定义但未使用:`acc'
关于你的PS:数组访问是 O (1),是的。但只是为了阅读当然;更新单个元素通常需要复制整个数组。
答案 1 :(得分:2)
您在步骤功能中意外使用了arr
而不是acc
。尝试将其更改为:
let sum_arr = foldl (\acc x -> acc//[(x, (acc ! x) + 1)]) arr nums
作为旁注,你应该总是使用严格的左侧折叠(Data.List.foldl&#39;)而不是懒惰的折叠。