OK.時間很快又過去了一周,第一周有五一假期是以感覺時間綽綽有餘,這周中間沒有假期隻能靠晚上加周末的時間來消化,其實還是有點緊張呢!後來發現每堂課的視訊還有對應的課件(Slide)、字幕(subtitles)可以下載下傳,這樣下載下傳視訊學習和線上學習就隻差課程中間的Exercise了
Week 2主要講函數,函數在Scala裡是first-class citizen,可以在任意域内出現,這門課其實也是在借Scala來講函數式程式設計原理。好了,不多說,進入習題解析。
這周的作業主要是使用函數來表示一個集合,可以通過傳遞給函數一個整型值得到布爾值來驗證此整型值是否屬于此集合。好,說太繞了,下面是給出的一個栗子:
這是一個匿名函數,将一個傳入的x映射為布爾值,進而判斷x是否屬于這個函數表示的集合。很明顯,這個集合是負整數集。
題目就從這裡開始,使用一個Int到Boolean的函數作為集合的表示,并給其賦了一個别名:
是以,在本此作業中定義的集合要以函數的形式給出。前面說到的函數是一等公民,當然可以作為傳回值。對應的,判斷一個值是否在給定集合内的方法如下:
可以看出contains函數傳進一個Set和一個Int作為參數,前面提到Set是一個輸入為Int類型的函數,是以将s應用到elem上,就得到一個Boolean類型的傳回值。
練習2.1完成集合的一些簡單操作的定義。
開始當然是定義一個集合啦~這個集合是個單例集合,其隻能存放一個值,簽名如下:
可以使用Int類型的參數來初始化這個函數,傳回的是一個Set類型,也就是Int => Boolean的函數。我們已經知道集合中隻包含elem這個元素,那麼隻需要判斷一個元素是否等于elem就可以了。
代碼自己寫吧……
上面我們定義了一個最簡單的集合,接下來可以通過簡單集合的不斷組合生成新的集合。比較常用的三種操作是union、intersect和diff,其原型如下:
以上三個操作均是通過組合兩個Set得到一個新的Set,分别表示兩個集合的并集、交集和差集,這些概念都比較簡單。
1.union就是在s中或者在t中的元素組成的集合,是以隻需要判斷一個元素是否在這兩者其一即可
2.intersect就是在s中且在t中的元素組成的集合,是以需要判斷一個元素是否同時在這兩者中
3.diff就是在s中且不在t中的元素組成的集合,需要判斷一個元素在s且不在t中
代碼,自己寫。
接下來是要實作一個filter函數,即選取集合s中符合斷言p的元素,這些元素組成的同樣是一個集合。filter的原型如下:
這個其實比較簡單了,實質上是intersect的變形,隻不過intersect的第二個入參是filter第二個入參的别名罷了。
作業2.2是完成一些在Set上的操作。
第一個函數給定一個斷言,判斷Set中的所有元素是否都滿足這個斷言。簽名如下:
我們定義Set的方式決定了無法實際列舉Set内的所有元素,隻能判斷給定元素是否屬于這個Set,是以如果要完成這個功能,我們需要周遊所有的整型數。這是不現實的,是以将其限定在-1000到1000範圍内。
對于以上的forall函數,題目給出了一個架構,隻需要在架構内把相應的部分(即???部分)填寫完畢即可:
可以看到forall内部定義了一個函數iter,并将一個iter的執行個體作為forall的傳回值(注意,這裡又強調了一次函數是一等公民的概念!)
那麼根據上述提示,我們需要周遊-1000到1000内的整型,依次判斷其是否符合斷言p,當然前提條件是這個整型也屬于集合s。p是一個Int映射到Boolean類型的函數,隻需要将整型數傳遞給它,判斷其傳回值即可知道此整型數是否符合p。判斷一個數是否屬于集合s可以使用Exercise 2.1中定義的contains函數來實作。
Main.scala中還定義了一個上界:
其實這個還是比較簡單,隻需要從-1000到1000,依次判斷其中屬于集合s的元素是否都符合斷言p即可。如果有一個不符合上述條件,那麼傳回false;如果都符合,傳回true。
請自行實作。
第二個需要實作的函數為exists,即判斷集合s中是否含有符合給定斷言的元素,簽名如下:
注意,題目要求exists需要通過調用forall來實作。這個場景好熟悉啊……這不就是高中課本裡的題目:“抛N枚硬币所有面都朝上的機率”,和“抛N枚硬币有一次面朝下的機率”之間的關系是一樣的麼?
OK,分析一下。判斷集合s中是否有符合給定斷言的元素,即判斷集合s中所有元素是否都不符合給定斷言。
如果s中所有元素都不符合給定斷言,那麼傳回false;否則傳回true。
懂了吧?下一題。
最後一道題目是寫一個map函數,将給定集合映射到另外一個集合,簽名如下:
其中第二個參數f是用來将原集合的元素映射到新集合的函數(一等公民!)
題目看起來簡單,隻是判斷s中的元素經過f映射後,是否有和輸入整型相等的即可。
這其中包含兩個步驟:
1.s中是否有符合某個特定條件(斷言)的元素
2.特定條件(斷言)為經過f映射,等于輸入參數
記得傳回類型為Set,即Int => Boolean類型的函數(一等公民!)!
總體來說,Scala有别于其他面向對象語言的一個最大的特點是其混合了很多函數式程式設計的概念和方法,這在使用Scala的過程中尤其要注意!Scala可以看做是O教(面向對象程式設計)和F教(函數式程式設計)的合體!
PS:此次附帶的FunSetSuite.scala中隻有很少一部分測試用例,還有一些是被打上了ignore标簽,如果自己有興趣,可以試着寫一些單元測試,保證能夠覆寫到一些特殊情況,這樣就不至于反複在Coursera的伺服器上送出不完美的答案了!
PPS:現在補上了作業題目的下載下傳連結和題面(防止網頁失效帶來的不便,以離線網頁的形式給出),方面以後看到的同學自己練習!
第二章題目下載下傳位址:
聲明:
本文為原創,禁止用于任何商業用途,轉載請注明出處: