十、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))
}
}
有任何问题都可以随时关注私信!
&spm=1001.2101.3001.5002&articleId=163763276&d=1&t=3&u=60a24e9808e84289ac4a80bb551d7f58)

被折叠的 条评论
为什么被折叠?



