【Scala】Scala的作业3----Scala学习笔记

1.读下图的程序,将其改为高阶函数的形式 。

题目一

/**
 * 1.读下图的程序,将其改为高阶函数的形式 。
 * 接收其他函数作为参数的函数,也被称作高阶函数(higher-order function)
 */
object MyModule {
  def main(args: Array[String]): Unit = {
    println(formatAbs(-42, abs))
  }

  def abs(n: Int): Int = {
    if (n < 0) -n else n
  }

  private def formatAbs(x: Int, func: (Int) => Int) = {
    val msg = "The absolute value of %d is %d"
    msg.format(x, func(x))
  }
}

2.用correspond方法让我们判断某个字符串数组里面所有元素的长度是否和某个给定的整数数组一致

/**
 * 2.用correspond方法让我们判断某个字符串数组里面
 * 所有元素的长度是否和某个给定的整数数组一致。
 */
object Correspond {
  def main(args: Array[String]): Unit = {
    val a = Array("hello", "world", "hadoop", "spark")
    val b = Array(5, 5, 6, 5)
    val c = Array(1, 2, 3)
    println(a.corresponds(b)(_.length == _)) //true则匹配
    println(a.corresponds(c)(_.length == _)) //false则不匹配
  }
}

3.假设某国的货币有若干面值,现给一张大面值的货币要兑换成零钱,问有多少种兑换方式。用尾递归实现。

/**
 * 3.假设某国的货币有若干面值,现给一张大面值的货币要兑换成零钱,
 * 问有多少种兑换方式。用尾递归实现。
 */
object ChangeMoney {
  //兑换零钱
  def changeMoney(money: Int, change: List[Int]): Int = {
    if (0 == money) return 1 //完成一种换法
    if (money < 0 || change.isEmpty) return 0 //该种换法没有成功
    changeMoney(money, change.tail) + changeMoney(money - change.head, change)

    /**
     * tail表示截取某列表的除首个元素以外的部分,数据类型依然是List[Int]
     * head表示获取某列表的除首个元素,数据类型是Int
     * changeMoney(money,change.tail)为按面值种类递归,每次删掉面值列表中的第一个面值(change.tail),求只用其余面值能得到的换法数量
     * changeMoney(money-change.head,change)为开始兑换,每次都用一种面值(change.head)进行兑换,能将money减为0的返回1(money-change.head)
     * 单独看后者递归,都是用同一种面值进行减法,但与前者相结合,所有递归下来就变成了每种面值都尝试过
     */
  }

  def main(args: Array[String]): Unit = {
    println(changeMoney(10, List(10, 5))) //1个10元  2个5元
    println(changeMoney(10, List(1, 2, 5, 10)))
  }
}

4.写一个递归函数,来获取第n个斐波那契数,前两个斐波那契数0 和 1,第n个数总是等于前两个数的和——序列开始为0,1,1,2,3,5.请定义尾递归函数 def fib(n: Int): Int

/**
 * 4.写一个递归函数,来获取第n个斐波那契数,前两个斐波那契数为0和1,第n个数总是等于前
 * 两个数的和——序列开始为0,1,1,2,3,5.请定义尾递归函数 def fib(n: Int): Int
 */
object Fibonacci {

  /**
   * Fib版本一
   * 尾递归
   * 有很大问题,因为f1和f2不是函数内变量,
   * 如果我们循环调用该函数,那么f1和f2会累加,会导致初始的前两位不为0和1
   */
  var f1 = 0
  var f2 = 1

  @scala.annotation.tailrec
  def fib(n: Int): Int = {
    if (n == 1) return f1
    val f3 = f1 + f2 //第三个数等于前两个数之和
    f1 = f2
    f2 = f3
    fib(n - 1)
  }

  /**
   * Fib版本二
   * 非尾递归
   *
   * @param n 第n个斐波那契数
   * @return 第n个斐波那契数的值
   */
  def fib1(n: Int): Int = {
    // 非尾递归
    if (n == 1)
      return 0
    if (n == 2)
      return 1
    fib1(n - 1) + fib1(n - 2)
  }

  /**
   * fib版本三 (老师的)
   * 尾递归
   *
   * @param n 第n个斐波那契数
   * @return 第n个斐波那契数的值
   */
  def fib2(n: Int): Int = {
    @scala.annotation.tailrec
    def loop(n: Int, prev: Int, curr: Int): Int =
      if (n == 1) prev
      else if (n == 2) curr
      else loop(n - 1, curr, prev + curr)

    loop(n, 0, 1)
  }


  def main(args: Array[String]): Unit = {
    //0,1,1,2,3,5,8,13
    println(fib(5)) //不能循环
    for (i <- 1 to 10)
      print(fib1(i) + " ")
    println()
    for (i <- 1 to 10)
      print(fib2(i) + " ")
  }
}

/*
 //大神代码  https://blog.csdn.net/Nougats/article/details/72903303
@scala.annotation.tailrec
def fib(n:Int, a:Int, b:Int): Int ={
  if(n==1) return a
  fib(n-1,b,a+b)
}*/

5.定义一个操作符+%,将一个给定的百分比添加到某个值。举例来说120 +% 10 = 132,由于操作符是方法而不是函数,你需要提供一个implicit。

/**
 * 5.定义一个操作符+%,将一个给定的百分比添加到某个值。举例来说120 +% 10 = 132,
 * 由于操作符是方法而不是函数,你需要提供一个implicit。
 */
object Operator {
  //隐式转换的声明必须在要使用的位置之前,否则无效
  //因为Double类型中并没有+%这个方法,所以这里把Double类型转换为A类型
  implicit def doubleToA(x: Double): A = new A(x)

  def main(args: Array[String]): Unit = {
    val res = 120 +% 10 //等价于new A(120).+%(10)
    new A(120).+%(10)
    println(res)
  }
}

class A(x: Double) {
  def +%(y: Double): Double = x * (1 + y * 0.01)
}

参考了这个大佬的代码:
https://blog.csdn.net/Nougats/article/details/72903303

posted @ 2019-11-26 17:36  爱做梦的子浩  阅读(259)  评论(0编辑  收藏  举报