我正在查找一些具有答案的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)
在这里实际发生了什么?
答案 0 :(得分:4)
首先,正如@AJFarmar指出的那样,编写rainfall
函数不是练习的一部分。答案只是提供了一个任意定义,因此您可以测试该解决方案,而数字3.9仅是凭空抽出的,以使降雨量看起来“很有趣”:
> rainfall 1
3.9
> rainfall 2
7.8
>
您真的不需要了解表达式是什么
fromIntegral (n `mod` 7) * 3.9
确实理解了该解决方案,但是如果您有兴趣,它将输入整数n
,计算出n `mod` 7
(n
除以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
,因此这是您应注意的部分。