折叠列表并累积到数组中

时间:2014-04-19 00:34:42

标签: arrays haskell

我尝试使用数组实现计数排序。

输入: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和不寻常的数组接口使我感到困惑。

2 个答案:

答案 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;)而不是懒惰的折叠。