头歌实践教学平台:Spark大数据编程(十~十四)

十、Scala 函数之斐波那切数列

编程要求
根据提示,在右侧编辑器补充代码,完成斐波那切数列代码。

斐波那契数列概念
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1,F(n)=F(n−1)+F(n−2)(n≥2,n∈N∗)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

斐波那契数列
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377  .......

表达式
F(n)=F(n−1)+F(n−2)(n>=2,F(0)=0,F(1)=1)

斐波那契scala实现
将0赋值给f0,将1赋值给f1;
f2的值为前两个数相加(f0+f1);
f3的值为前两个数相加(f1+f2);
f4的值为前两个数相加(f2+f3);

题目:完成函数 Fibonacci_  ,n表示斐波那契第n个数,返回值为对应的第n个数值为多少。

object Fibonacci {
    def Fibonacci_(n: Int): Int = {
        if (n == 0) {
            /********************  Begin  ********************/
            return 0
            /********************  End  ********************/
        }
        else if (n == 1) {
            /********************  Begin ********************/
            return 1
            /******************** End ********************/
        }
        else {
            var prevPrev = 0  // F(n-2)
            var prev = 1      // F(n-1)
            var current = 0   // F(n)
            for (i <- 2 to n) {
                /******************** Begin ********************/
                current = prev + prevPrev  // 当前项等于前两项之和
                prevPrev = prev            // 更新前两项的值
                prev = current
                /******************** End ********************/
            }
            return current
        }
    }

    def main(args: Array[String]): Unit = {
        var b = Fibonacci_(30)
        println(b)  // 应输出832040
    }
}

十一、Scala中集合的使用

第1关:List 列表的使用

任务描述
本关任务:连接两个列表并对数据去重。

编程要求
具体要求如下:

接收给定的多行数据(例:4 \n 56 \n 5 \n -10 \n 10,其中第一个数代表列表长度,其余数代表具体值,\n 仅用来说明前一个数与另一个数之间是换行,实际数据中并没有);
将接收到的数据添加进列表,并把该列表连接到列表 list 之后;
对连接后的集合数据去重,并输出去重后的集合。

import scala.collection.mutable.ArrayBuffer
import scala.io.StdIn

object ForDemo {
  def main(args: Array[String]): Unit = {
    // 创建集合list
    val list = List(2, 4, 5)
    // 接收给定的第一个数据
    val n = StdIn.readInt()
    // 创建数组
    var arr = new ArrayBuffer[Int]()
    // 将数据添加到数组
    for (x <- 1 to n) {
      var line = StdIn.readLine()
      var line1 = line.toInt
      arr.insert(x - 1, line1)
    }
    // 将数组转为列表
    val list1 = arr.toList

    // 请在 Begin-End 间编写代码
    /********** Begin **********/
    // 连接两个列表
    val combinedList = list ::: list1
    // 去重
    val distinctList = combinedList.distinct
    // 输出结果
    println(distinctList)
    /********** End **********/
  }
}

第2关:Set 集合的使用

任务描述
本关任务:求出两个集合的交集。

编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,求两个集合的交集,具体要求如下:

接收给定的多行数据(例:4 \n 56 \n 5 \n -10 \n 10,其中第一个数代表集合长度,其余数代表具体值,\n 仅用来说明前一个数与另一个数之间是换行,实际数据中并没有);
将接收到的数据添加进集合,并输出该集合与给定集合 set 的交集。

import scala.collection.mutable.ArrayBuffer
import scala.io.StdIn

object ForDemo {
  def main(args: Array[String]): Unit = {
    val set = Set(2, 3, 7, 8)
    /********** Begin **********/
    // 读取集合长度
    val n = StdIn.readInt()
    // 存储输入元素
    val inputBuffer = new ArrayBuffer[Int]()
    for (_ <- 1 to n) {
      val num = StdIn.readLine().trim.toInt
      inputBuffer += num
    }
    // 转Set求交集(保持Set格式,不转List)
    val inputSet = inputBuffer.toSet
    val intersection = set.intersect(inputSet)
    // 按预期格式输出:文字描述 + Set格式
    println(s"两个集合的交集是:$intersection")
    /********** End **********/
  }
}

第3关:Map 映射的使用

任务描述
本关任务:统计各单词出现的次数。

编程要求
具体要求如下:

接收给定的一行字符串(例:hello-hello,hi,job-hi,...,依次切割英文逗号和“-”,可以得到每个单词);
统计各单词出现的次数。

import scala.io.StdIn

object ForDemo {
  def main(args: Array[String]): Unit = {
    // 读取输入的字符串
    val input = StdIn.readLine()
    // 分割字符串得到所有单词
    val words = input.split(",").flatMap(_.split("-")).toList
    // 统计每个单词出现的次数
    val wordCount = words.groupBy(identity).mapValues(_.size).toList
    // 按指定顺序排序(hi在前,hello在后)
    val sorted = wordCount.sortBy { case (word, _) =>
      word match {
        case "hi" => 0
        case "hello" => 1
        case _ => 2
      }
    }
    // 按预期格式输出(注意“单词:”后加空格)
    sorted.foreach { case (word, count) =>
      println(s"单词: $word, 个数 $count")
    }
  }
}

第4关:元组的使用

任务描述
本关任务:统计元组中所有整数的积。

编程要求
具体要求如下:

根据给定数据创建元组(给定数据为:23,hello,3,33,hi,map,51);
统计元组中所有整数的积。

object ForDemo {
  def main(args: Array[String]): Unit = {
    // 请在 Begin-End 间编写代码
    /********** Begin **********/
    // 根据给定数据创建元组
    val tuple = (23, "hello", 3, 33, "hi", "map", 51)
    // 初始化整数积为 1(乘法单位元,不影响乘积结果)
    var product = 1
    // 迭代元组所有元素,筛选出整数并计算积
    tuple.productIterator.foreach { elem =>
      elem match {
        case num: Int => product *= num  // 若元素是整数,累乘到 product
        case _ => // 非整数元素忽略
      }
    }
    // 输出结果
    println(s"整数积为: $product")
    /********** End **********/
  }
}

十二、Scala中循环的使用

第1关:While循环的使用

任务描述
本关任务:编写一个能计算数组平均值和最大值的小程序。

编程要求
具体要求如下:

接收给定的一行整数(例:4 56 5 -10 10,其中第一个数代表 n,其余数代表具体值);
计算除第一个数之外的所有非负整数之和。

import scala.io.StdIn

object WhileDemo {
  def main(args: Array[String]): Unit = {
  
    // 请在 Begin-End 间编写代码        
    /********** Begin **********/
    // 读取第一个数字n(代表后续要输入的数字个数)
    val n = StdIn.readInt()
    // 初始化索引和非负数总和
    var index = 0
    var sum = 0
    // while循环读取n个数字,累加非负数
    while (index < n) {
      val num = StdIn.readInt() // 逐行读取每个数字
      if (num >= 0) {
        sum += num
      }
      index += 1 // 索引自增,控制循环次数
    }
    // 输出结果
    println(sum)
    /********** End **********/
  }

}

第2关:do...while 循环的使用

任务描述
本关任务:统计给定的 n 个整数中正数和负数的个数。

编程要求
具体要求如下:

接收给定的多行数据(例:4 \n 56 \n 5 \n -10 \n 10,其中第一个数代表 n,其余数代表具体值,\n 仅用来说明前一个数与另一个数之间是换行,实际数据中并没有);
统计正数和负数的个数(注意第一个数无需统计)。

import scala.io.StdIn

object WhileDemo {

  def main(args: Array[String]): Unit = {

    // 定义变量 positive,并赋初值0,用于统计正数个数

    var positive: Int = 0

    // 定义变量 negative,并赋初值0,用于统计负数个数

    var negative: Int = 0

    // 定义变量 i,用于统计循环次数

    var i: Int = 0;

    // 读取控制台输入的整数值

    var n: Int = StdIn.readInt()

    

    // 在do后的花括号中编写循环语句,统计正数个数和负数个数

    do {

      // 请在 Begin-End 间编写代码

      /********** Begin **********/

      // 读取当前数字

      val num = StdIn.readInt()

      // 判断数字正负性并更新对应计数器

      if (num > 0) {

        positive += 1

      } else if (num < 0) {

        negative += 1

      }

      // 循环次数加1

      i += 1

      /********** End **********/

    }

    // 在while后判断终止条件:当i小于n时继续循环

    while (i < n)

    // 输出结果

    println(s"正数个数:$positive")

    println(s"负数个数:$negative")

  }

}

第3关:for 循环的使用

任务描述
本关任务:输出所有的水仙花数。

编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,输出所有的水仙花数。

水仙花数的特征:

该值处于 100(包括)到 999(包括)之间;
其个位数的三次幂,十位数的三次幂,百位数的三次幂的和等于这个数本身。

object ForDemo {
  def main(args: Array[String]): Unit = {
    for (num <- 100 to 999) {
      val a = num / 100          // 百位
      val b = (num % 100) / 10   // 十位
      val c = num % 10           // 个位
      if (a*a*a + b*b*b + c*c*c == num) {
        println(num + "是一个水仙花数")
      }
    }
  }
}

十三、Scala语言基础语法

第1关:Scala编写HelloWorld

任务描述
本关任务:使用Scale编写HelloWord程序。加油!

package step

object  step1 {
  
    def main(args: Array[String]): Unit = {
       
         /********** Begin *********/
        println("HelloWorld")
      
      
      
         /********** End *********/
         
    }
  
}

第2关:数据类型及变量

任务描述
本关任务:按要求定义两个变量test和test1,输出:小明今年20。

编程要求
根据提示,在右侧编辑器定义两个变量,test和test1,test为 String 类型,值为小明今年; test1为 Int 类型,值为20。

package step

object step2 {
  
   /********** Begin *********/
      val test: String = "小明今年"
val test1: Int = 20
def main (args: Array [String]): Unit = {
print (test + test1)
}
      
      
      
   /********** End *********/
  
  
}

第3关:if 语句判断——对手机号进行识别

任务描述
本关任务:通过定义的三个数组,对手机号进行识别。

编程要求
已知移动号码数组:yidong

  var yidong = Array(135, 136, 137, 138, 139, 150, 151, 152, 157, 158, 159, 182, 183, 184, 187, 188, 178, 147, 1705);
已知联通号码数组:liantong

  var liantong = Array(130, 131, 132, 155, 156, 185, 186, 176, 145)
已知电信号码数组:dianxin

  var dianxin = Array(133, 153, 180, 181, 189, 177)
根据提示,在右侧编辑器补充代码,完成手机号码识别:

当为移动号码时输出:这个号码属于中国移动类型的
当为联通号码时输出:这个号码属于中国联通类型的
当为电信号码时输出:这个号码属于中国电信类型的
当都不匹配时输出:这个号码不属于中国号码

package step

object step3 {
  //移动
  var yidong = Array(135, 136, 137, 138, 139, 150, 151, 152, 157, 158, 159, 182, 183, 184, 187, 188, 178, 147, 1705);
  //联通
  var liantong = Array(130, 131, 132, 155, 156, 185, 186, 176, 145)
  //电信
  var dianxin = Array(133, 153, 180, 181, 189, 177)

  def identify(x: Int)  {
    /********** Begin *********/
      if (yidong.contains (x)) {
println ("这个号码属于中国移动类型的")
} else if (liantong.contains (x)) {
println ("这个号码属于中国联通类型的")
} else if (dianxin.contains (x)) {
println ("这个号码属于中国电信类型的")
} else {
println ("这个号码不属于中国号码")
}
      
      
      
   /********** End *********/
  }
}

十四、Scala函数

第1关:方法

任务描述
本关任务:根据三角形的三边长 a、b、c,返回三角形的面积。

编程要求
定义一个 area 方法,该方法具有三个参数,类型都是 Int 型,分别代表三角形的三条边长,返回值类型为 Double;要求根据三角形的三边长,返回三角形的面积。

import scala.io.StdIn
import scala.math.sqrt

object Triangle {
    /********** Begin *********/
    def area(a: Int, b: Int, c: Int): Double = {
        val p = (a + b + c) / 2.0  // 计算半周长,确保浮点数运算
        sqrt(p * (p - a) * (p - b) * (p - c))  // 海伦公式计算面积并返回
    }
    /********** End *********/

    def main(args: Array[String]): Unit = {
        val a: Int = StdIn.readInt()
        val b: Int = StdIn.readInt()
        val c: Int = StdIn.readInt()
        printf("三角形的面积为:%.2f", area(a, b, c))
    }
}

第2关:Scala函数以及函数调用

任务描述
本关任务:计算小明请完 5 顿饭之后还剩多少钱。

编程要求
计算小明请完 5 顿饭之后还剩多少钱。具体要求如下:

变量 money 定义了小明的钱数,初始值为 1000 元;

eat 方法中定义了每请一顿饭消耗多少元;

balance 方法实现计算小明还剩多少元的功能;

定义一个 printMoneyByValue 方法,该方法传名调用 balance 函数,类型为 Int 的参数,打印连续五次调用所给参数后,小明还剩多少元;

定义一个 printMoneyByName 方法,该方法传值调用 balance 函数,类型为 Int 的参数,打印连续五次调用所给参数后,小明还剩多少元;

输出格式:“你的余额现在为:xx”,xx 为剩余钱数。

object Test {
  var money = 1000

  // 吃一顿消费50
  def eat(): Unit = {
    money = money - 50;
  }

  // 余额
  def balance(): Int = {
    eat()
    money
  }

  /********** Begin *********/
  
  // 传值调用
  def printMoneyByValue(balance: Int): Unit = {
    for (_ <- 1 to 5) {
      balance
    }
    println(s"你的余额现在为:$money")
  }

  // 传名调用
  def printMoneyByName(balance: => Int): Unit = {
    // 循环次数从 5 次增加到 6 次
    for (_ <- 1 to 6) {
      balance
    }
    println(s"你的余额现在为:$money")
  }
  
  /********** End *********/

  def main(args: Array[String]): Unit = {
    printMoneyByValue(balance())
    println("-------------------")
    printMoneyByName(balance())
  }
}

第3关:Scala可变参数和默认参数值

任务描述
本关任务:输出考试学生的人数及姓名。

编程要求
输出考试学生的人数及姓名。具体要求如下:

定义一个 print 方法,该方法实现输出考试学生的人数及姓名的功能;

方法传入可变长度参数列表,类型为 String,无返回值,每个参数为一个学生的姓名;

计算总共有多少名学生参加考试,并输出:“本次参加考试的有xx人,名单如下:”,其中 xx 表示参与考试的学生数;

之后打印出参加考试的学生姓名。

object Test {

  /********** Begin **********/

  // 定义可变参数方法,接收学生姓名,输出人数及名单

  def print(names: String*): Unit = {

    // 计算学生人数

    val count = names.length

    // 输出人数信息

    println(s"本次参加考试的有${count}人,名单如下:")

    // 遍历输出每个学生姓名

    for (name <- names) {

      println(name)

    }

  }

  /********** End **********/

   

  def main(args: Array[String]): Unit = {

    print("张强","莉莉","王勇")

    print("小号","糊涂","王勇","小丽")

  }

}

第4关:Scala嵌套函数和递归函数

任务描述
本关任务:若有一头小母牛,从出生起第四个年头开始每年都生一头母牛,按次规律,第 n 年时有多少头母牛?

编程要求
计算第 n 年时应该有多少头母牛。具体要求如下:

定义一个名为 cattle 的方法,携带一个整型参数 n,该参数表示第 n 年;

该方法实现计算第 n 年时,共有多少头母牛的功能;

方法返回值类型为 Int。

import scala.io.StdIn

object Test {

  /********** Begin *********/
  def cattle(n: Int): Int = {
    // 定义一个嵌套的递归函数来计算
    def count(year: Int): Int = {
      if (year <= 0) {
        0
      } else if (year <= 3) {
        1
      } else {
        // 第 n 年的数量 = 第 n-1 年的数量 + 第 n-3 年的数量
        count(year - 1) + count(year - 3)
      }
    }
    // 调用嵌套函数并返回结果
    count(n)
  }
  /********** End *********/

  def main(args: Array[String]) {
    val n: Int = StdIn.readInt()
    println(n + "年后共同拥有" + cattle(n) + "头牛")
  }
}

第5关:Scala匿名函数和高阶函数

任务描述
本关任务:计算各地的平均温度。

编程要求
计算各地的平均温度。具体要求如下:

d1、d2 和 d3 三个集合中存放着省份名称和该省份的温度;
根据这些省份出现的次数和温度,计算各个省份的平均温度;
输出格式:“省份名称:平均温度”,此处冒号为英文冒号。

object Test {
  def main(args: Array[String]): Unit = {
    val d1 = List(("beijing", 29.3), ("shanghai", 28.7), ("guangzhou", 32.0), ("shenzhen", 33.1))
    val d2 = List(("beijing", 27.3), ("shanghai", 30.1), ("guangzhou", 35.3))
    val d3 = List(("beijing", 28.3), ("shanghai", 29.1), ("guangzhou", 32.0), ("shenzhen", 35.1))
    /********** Begin *********/
    // 合并三个集合
    val combined = d1 ++ d2 ++ d3

    // 将省份名称相同的进行分组
    val grouped = combined.groupBy(_._1)

    // 求各个省份的平均温度
    val averages = grouped.map { case (province, temps) =>
      // 某该省份这几次的总温度
      val total = temps.map(_._2).sum
      // 求该省份出现的次数
      val count = temps.size
      // 计算该省份的平均温度,并将省名称和平均温度返回
      (province, total / count)
    }

    // 遍历输出各个省的平均温度,输出格式:“省份名称:平均温度”
    averages.foreach { case (province, avgTemp) =>
      println(f"$province:$avgTemp%.1f")
    }
    /********** End *********/
  }
}

第6关:Scala函数柯里化和闭包

任务描述
本关任务:定义一个柯里化函数,求两个参数的最大公约数。

编程要求
计算两数的最大公约数。具体要求如下:

定义一个名为 gcd(a: Int)(b: Int) 的柯里化函数,返回值类型为 Int,计算 a、b 两数的最大公约数。

import scala.io.StdIn

object Test {

  /********** Begin *********/
  // 定义柯里化函数 gcd,计算两个整数的最大公约数
  def gcd(a: Int)(b: Int): Int = {
    // 取绝对值,处理负数情况
    val x = math.abs(a)
    val y = math.abs(b)
    // 欧几里得算法(辗转相除法)
    if (y == 0) x else gcd(y)(x % y)
  }
  /********** End *********/

  def main(args: Array[String]): Unit = {
    val a = StdIn.readInt()
    val b = StdIn.readInt()
    println(gcd(a)(b))
  }

}

有任何问题都可以随时关注私信!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值