coursera作业之(集合)函数对象

17 篇文章 0 订阅
8 篇文章 0 订阅

第二次作业


这次作业做了大约两小时,大部分时间是花在了map和exists上
其中map,我一开始的答案是
  def map(s: Set, f: Int => Int): Set = {
    x=>s(f(x)) // ERROR
  }
但是这样的话,因果关系就反掉了,假如s = {9}, f: x=>x/3
那么最终的返回值其实是x=>s(x/3),也就是x/3要在s这个Set里存在,也就是说,返回值是{27}
所以最后仍然用了遍历,每当有和x/3相等的值时,就加入集合,最后返回这个集合

exists
挺难的,而且我觉得,就正如题目的Hint所说:
this assignment needs more thinking (whiteboard, pen and paper) than coding ;-). 
因为这道exists其实不是考察编程能力,而是分析能力
我最后的思路是想到了数学中的集合运算,因为题目的要求是exists必须用到forall函数,可是我实在想不出有什么原因要用到它
后来把思路拓展到数学集合运算,发现forall(x,y)其实就是判断前者x是否是后者y的子集
而exists就是算出两个集合有没有非空公共子集,但是有个问题:空集是任何集合的子集,不能直接用interfact
最后苦思冥想想到:
exists 等价于  两个集合x,y有非空公共子集,等价于 两个集合x,y没有非空公共子集的取反, 等价于x集合取反是y的子集 逻辑与 && y 集合取反是x的子集
但是一个集合的取反要靠辅助函数构造一个全集,然后diff(全集,某个集合) 实现,于是最后代码如下:
!(forall(s, diff( ful , p)) && forall(p, diff(  ful , s)))

https://class.coursera.org/progfun-003/assignment/view?assignment_id=3

package   funsets

import   common._

/**
 * 2. Purely Functional Sets.
 */
object   FunSets {
    /**
   * We represent a set by its characteristic function, i.e.
   * its `contains` predicate.
   */
    type   Set = Int => Boolean

    /**
   * Indicates whether a set contains a given element.
   */
    def   contains(s: Set, elem: Int): Boolean = s(elem)

    /**
   * Returns the set of the one given element.
   */
    def   singletonSet(elem: Int): Set = {
    x: Int => x == elem
  }

    /**
   * Returns the union of the two given sets,
   * the sets of all elements that are in either `s` or `t`.
   */
    def   union(s: Set, t: Set): Set = {
    x: Int => s(x) || t(x)
  }

    /**
   * Returns the intersection of the two given sets,
   * the set of all elements that are both in `s` and `t`.
   */
    def   intersect(s: Set, t: Set): Set = {
    x: Int => s(x) && t(x)
  }

    /**
   * Returns the difference of the two given sets,
   * the set of all elements of `s` that are not in `t`.
   */
    def   diff(s: Set, t: Set): Set = {
    x: Int => s(x) && !t(x)
  }

    /**
   * Returns the subset of `s` for which `p` holds.
   */
    def   filter(s: Set, p: Int => Boolean): Set = {
    x: Int => s(x) && p(x)
  }

    /**
   * The bounds for ` forall` and `exists` are +/- 1000.
   */
    val   bound   =   1000

    /**
   * Returns whether all bounded integers within `s` satisfy `p`.
   */
    def   forall(s: Set, p: Int => Boolean): Boolean = {
      /**
     * 1. Consider  p: Int => Boolean  as a Set
     * 2. Consider function as an object
     */
      def   iter(a: Int): Boolean = {
        if   (a >   bound )   true
        else   if   (s(a) && !p(a))   false
        else   iter(a +   1 )
    }
    iter(- bound )
  }

    /**
   * Returns whether there exists a bounded integer within `s`
   * that satisfies `p`.
   */
    def   exists(s: Set, p: Int => Boolean): Boolean = {
      def   iter(a: Int, set: Set): Set = {
        if   (a >   bound ) set
        else   iter(a +   1 , union(set, singletonSet(a)))
    }
      val   ful   = iter(-   bound ,   Set ())
    !(forall(s, diff( ful , p)) && forall(p, diff(   ful , s)))
  }

    /**
   * Returns a set transformed by applying `f` to each element of `s`.
   */
    def   map(s: Set, f: Int => Int): Set = {
      def   iter(a: Int, set: Set): Set = {
        if   (a >   bound ) set
        else   if   (s(a)) iter(a +   1   , union(set, singletonSet(f(a))))
        else   iter(a +   1 , set)
    }
    iter(- bound ,   Set ())
      // x=>s(f(x)) // ERROR
  }

    /**
   * Displays the contents of a set
   */
    def   toString(s: Set): String = {
      val   xs   =   for   (   i   <- - bound   to   bound   if   contains(s, i))   yield   i
      xs .mkString(   "{" ,   ","   ,   "}"   )
  }

    /**
   * Prints the contents of a set on the console.
   */
    def   printSet(s: Set) {
    println(toString(s))
  }
}

new   TestSets {
    val   r   = union( s1 ,   s3 )
    val   s   = union( s1 ,   s2 )
    val   t   = union( s1 ,   s2 )
  assert(forall( s ,   t ),   "forall 1" )
  assert(!forall( s ,   r ),   "forall 2" )

  assert(exists( s ,   r ),   "exists 1" )

    val   sMap   = singletonSet(   9 )
  assert(exists(map( sMap , x => x /   3 ),   s3 ),   "exists 2" )
  assert(exists( s1 ,   s1 ),   "exists 3" )
  assert(!exists( s2 ,   r ),   "exists 4" )
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值