计算一组箱子中的频率

时间:2014-11-21 16:23:49

标签: haskell

我需要计算列表中值之间的值,即[135,136,138,140]将计算135-136,136-138,138-140之间的所有数字。输入列表[135.2,135.3,137,139]将使用[Float] [Float] [Int]类型输出[2,1,1]。到目前为止,我有:

 heightbetween :: Float -> Float -> [Float] -> Int
 heightbetween _ _ [] = 0
 heightbetween n s (x:xs) 
     | (n < x) && (s > x) = 1 + (heightbetween n s xs)
     | otherwise = heightbetween n s xs

  count :: [Float] -> [Float] -> [Int]
  count [] [] = []
  count [x,y] = [(x,y)]
  count (x:y:ys) = (x,y):count (y:ys)

  forEach fun lst = heightbetween op ([],lst)
    where
  op (start,[]) = Nothing
  op (start,a:as) = Just (start++(fun a):as
                        ,(start++[a],as)) 

 forPairs fun lst lst2 = map (map fst) 
                     $ forEach (\(a,b)->(fun a b,b))
                     $ zip lst lst2

2 个答案:

答案 0 :(得分:0)

你的count看起来很奇怪。它应该是这样的:

-- count -> ranges -> data -> [counts]
count :: [Float] -> [Float] -> [Int]
count [] _ = []     -- no ranges given -> empty list 
count [_] _ = []    -- no ranges, but single number -> empty list
count _ [] = []     -- no data given -> empty list
count (x:y:xs) d = 
    (heightbetween x y d) : count (y:xs) d

heightbetween :: Float -> Float -> [Float] -> Int
heightbetween _ _ [] = 0
heightbetween n s (x:xs) 
    | (n < x) && (s > x) = 1 + (heightbetween n s xs)
    | otherwise = heightbetween n s xs

其他线路已过时。 然后调用

 count [135,136,138,140]  [135.2,135.3,137,139]

给出

[2,1,1]

答案 1 :(得分:0)

首先,确保您的范围列表有序......

rangePoints =  [135,136,138,140]

orderedRangePoints = sort rangePoints

接下来,您会发现使用实际范围(您可以使用2元组(low,high)表示)更容易

ranges = zip orderedRangePoints $ tail orderedRangePoints

你需要一个inRange函数(Data.Ix中已存在一个函数,但不幸的是它包含了upperbound,所以你不能使用它)

inRange (low,high) val | val >= low && val < high = True
inRange _ _ = False

您还需要订购输入点

theData = sort [135.2,135.3,137,139]

完成所有这些操作后,binCount函数很容易编写。

binCount'::[(Float, Float)]->[Float]->[Int]
binCount' [] [] = []
binCount' (range:rest) vals = 
      length valsInRange:binCount' rest valsAboveRange
      where
          (valsInRange, valsAboveRange) = span (`inRange` range) vals

注意,我定义了一个名为binCount'的函数,而不是binCount。我这样做了,因为我认为这是一个不安全的函数,因为它只适用于有序范围和值....你应该通过编写一个更安全的binCount函数来完成它,它将所有上面的东西都放在它的位置条款。您应该添加所有类型和一些错误检查(如果值超出所有范围会发生什么?)。