你能帮我了解一下这段代码如何工作吗?

时间:2018-09-22 20:20:35

标签: haskell

我正在查找一些具有答案的Haskell练习。 这是练习:

  

假设您有一个rainfall函数,该函数可计算给定一周(每周从1开始的数字)中城市的降雨量

type WeekNumber = Int
rainfall :: WeekNumber -> Double    -- assume this function exists
     

完成以下函数的定义:

mostRain :: WeekNumber -> Double
mostRain n | n < 1     = 0
           | otherwise =                       -- (complete this case)
     

您的解决方案必须是递归的。提示:函数max可能有用。请注意,您不必为函数rainfall提供定义。

答案:

import Data.List
import Data.Maybe
import Test.QuickCheck
-- 1 ----------------
type WeekNumber = Int
rainfall :: WeekNumber -> Double
rainfall n = fromIntegral (n `mod` 7) * 3.9

mostRain :: WeekNumber -> Double
mostRain n | n < 1     = 0
           | otherwise =  rainfall n `max` mostRain (n - 1) 

我真的希望有人能帮助我向他们解释这个数字3.9 (n `mod` 7) * 3.9

以及otherwise = rainfall n `max` mostRain (n - 1)在这里实际发生了什么?

2 个答案:

答案 0 :(得分:4)

首先,正如@AJFarmar指出的那样,编写rainfall函数不是练习的一部分。答案只是提供了一个任意定义,因此您可以测试该解决方案,而数字3.9仅是凭空抽出的,以使降雨量看起来“很有趣”:

> rainfall 1
3.9
> rainfall 2
7.8
>

您真的不需要了解表达式是什么

fromIntegral (n `mod` 7) * 3.9

确实理解了该解决方案,但是如果您有兴趣,它将输入整数n,计算出n `mod` 7n除以7后的余数,因此它将1、2、3、4、5、6、7、8、9、10变成1、2、3、4、5、6、0、1、2、3),并将结果转换为整数乘以3.9之前的两倍。因此,例如,这给出了第1至10周的降雨量,如下所示:

> map rainfall [1..10]
[3.9,7.8,11.7,15.6,19.5,23.4,0.0,3.9,7.8,11.7]
>

要了解otherwise之后的解决方案部分,首先让我们重写它以摆脱特殊的反引号表示法:

mostRain :: WeekNumber -> Double
mostRain n | n < 1     = 0
           | otherwise =  max (rainfall n) (mostRain (n - 1))

此定义表示,如果mostRain n,则在第1到n周内看到的最多降雨的计算0将定义为n < 1,否则通过以下表达式: / p>

max (rainfall n) (mostRain (n - 1))

此表达式计算两个数中的最大值,即rainfall n的值(即n周的降雨量)和mostRain (n - 1)的值。这是一个递归调用,它将计算在n-1的第1周内看到的最多降雨。

因此,这实际上是说,第1周到第n周的最大降雨量被定义为(1)第n周的最大降雨量和(2)前几周出现的最大降雨量。另外,您可以将其视为按以下步骤执行计算:

mostRain 3
= max (rainfall 3) (mostRain 2)
= max (rainfall 3) (max (rainfall 2) (mostRain 1))
= max (rainfall 3) (max (rainfall 2) (max (rainfall 1) (mostRain 0))
= max (rainfall 3) (max (rainfall 2) (max (rainfall 1) 0)

如果我们填写模拟的降雨量,您将看到它最终如何计算​​最大值:

= max 11.7 (max 7.8 (max 3.9 0)
= max 11.7 (max 7.8 3.9)
= max 11.7 7.8
= 11.7

答案 1 :(得分:2)

请注意,说明中对此进行了说明:

  

public static int[] removeDups(int[] a1, int[] a2) { //count the number of duplicate values found in the first array int dups = 0; for (int i = 0; i < a1.length; i++) { for (int j = 0; j < a2.length; j++) { if (a1[i] == a2[j]) { dups++; } } } //to find the size of the new array subtract the counter from the length of the first array int size = a1.length - dups; //create the size of the new array int[] result = new int[size]; //populate the new array with the unique values for (int i = 0; i < a1.length; i++) { int count = 0; for (int j = 0; j < a2.length; j++) { if (a1[i] != a2[j]) { count++; if (count < 2) { result[i] = a1[i]; } } } } return result; }

也就是说,实际上并不需要您定义rainfall :: WeekNumber -> Double -- assume this function exists他们在解决方案中给出的定义只是示例定义-3.9完全是任意的。忽略它。

您只应定义rainfall,因此这是您应注意的部分。