Haskell数字列表处理



我在完成这个问题时遇到问题。任何可能的解决方案的提示将不胜感激。

给定一个Doublev和一个Double值列表xscalcList返回一个Double根据以下规则:

  1. 对于xsx的每个值,如果x不为正,则输出列表中将没有相应的值。

  2. 否则,相应的输出值将x * ln x

  3. 但是,当且仅当其值大于 v 时,此值才会出现在输出列表中。

  4. 相应输出值(如果存在(的顺序应与输入相同值。

以下是一些示例:

calcList 1.0 [] = []
calcList 1.0 [3.0] = [3.2958]
calcList 1.0 [-1.0, 1.0, 3.0, 5.0, 7.0, 9.0] = [3.2958, 8.0472, 13.6214, 19.7750]
calcList 100.0 [1.0 .. 40.0] = [102.0359, 106.4536, 110.9035, 115.3847, 119.8963, 124.4372, 129.0067, 133.6040, 138.2283, 142.8789, 147.5552]

到目前为止,我拥有的:

positive :: Double -> Bool
positive x = x > 0.0
calcValue :: Double -> Double
calcValue x = log x * x
calcList :: Double -> [Double] -> [Double]
calcList v xs = []
calcList v xs

所以看起来有 3 个步骤。

  1. 去除元素 <= 0 ( filter (
  2. 将每个剩余元素乘以其自然对数(map(
  3. 摆脱元素 <= v ( filter (

我们可以使用 (.) (自 f.g == x -> f (g x) 以来(来组合函数,而不是将这些分别应用于输入。

calcList = v -> filter (>v) . map (x -> x*log x) . filter (>0)

您应该查看filtermap上的文档。此外,《学习你一个哈斯克尔》中的这一章将是一个很好的阅读。

我们可以使用一种方法,其中我们使用filter ,和 map 。可以通过列表理解获得等效的解决方案:

calcList :: (Ord d, Floating d) => d -> [d] -> [d]
calcList v xs = [xlogx | x <- xs, x > 0, let xlogx = x * log x, xlogx > v]

因此,我们在这里使用x <- xs来迭代xs中的元素,通过使用x > 0我们过滤值,以便只考虑x > 0的值。接下来我们将变量xlogx定义为 let xlogx = x * log x ,然后我们有一个额外的过滤器来检查是否xlogx > v

列表推导式的 yield 部分(管道字符 | 之前的部分(指定我们将xlogx添加到列表中。

另一种方法是

calcList :: Double -> [Double] -> [Double]
calcList v [] = []
calcList v (x:xs) = case (positive x) of {
                   False -> calcList v xs;
                   True -> case ((calcValue x) > v) of {
                            False -> calcList v xs;
                            True -> (calcValue x):(calcList v xs);
                   };
}

在每个cases中,您检查其中一个条件,并在列表开头添加数字,以便顺序相同。

最新更新