第一题、百元喝酒

作业要求:每瓶啤酒2元,3个空酒瓶或者5个瓶盖可换1瓶啤酒。100元最多可喝多少瓶啤酒?(不允许借啤酒)

思路:利用递归算法,一次性买完,然后递归算出瓶盖和空瓶能换的啤酒数

/**
* @author DOUBLEXI
* @date 2021/8/17 15:33
* @description
*
* 作业要求:每瓶啤酒2元,3个空酒瓶或者5个瓶盖可换1瓶啤酒。100元最多可喝多少瓶啤酒?
* (不允许借啤酒)思路:利用递归算法,一次性买完,然后递归算出瓶盖和空瓶能换的啤酒数
*/
object HundredBeer {
/**
* @param sumBeers 啤酒总数
* @param bottle 剩余空瓶子数量
* @param cap 剩余啤酒盖数量
* @return 返回总啤酒总数
*/
def beer(sumBeers: Int, bottle: Int, cap: Int): Int = {
println(s"啤酒总数:$sumBeers,剩余空瓶子:$bottle,剩余啤酒盖:$cap")
// 递归边界条件
if (bottle < 3 && cap < 5) return sumBeers
var b1 = bottle / 3 // 现有空瓶子能够兑换的啤酒数
var b2 = bottle % 3 // 空瓶子兑换啤酒后,剩余的空瓶子
var c1 = cap / 5 // 现有啤酒盖能够兑换的啤酒数
var c2 = cap % 5 // 啤酒盖兑换啤酒后,剩余的空瓶子
/*
上面一顿兑换操作后,啤酒总数为:b1 + c1 + sumBeers
剩余的空瓶子总数为:b1 + c1 + b2
剩余的啤酒盖总数为:b1 + c1 + c2
继续递归兑换
*/
beer(b1 + c1 + sumBeers, b1 + c1 + b2, b1 + c1 + c2)
} def main(args: Array[String]): Unit = {
var sumBeers: Int = 100 / 2 // 初始化啤酒总数
var bottle, cap : Int = sumBeers // 初始化空瓶子数=啤酒盖数=啤酒总数
val beers = beer(sumBeers, bottle, cap) // 递归求能够喝到的啤酒总数
println(s"100元最多可以喝$beers 瓶啤酒")
}
}

运行结果如下:

第二题、人机猜拳

1.1 作业需求

1. 选取对战角色

2. 开始对战,用户出拳,与对手进行比较,提示胜负信息

3. 猜拳结束算分,平局都加一分,获胜加二分,失败不加分

4 . 循环对战,当输入“n”时,终止对战,并显示对战结果

5. 游戏结束后显示得分

如下图所示:

1.2 作业分析

分析业务逻辑,抽象出类、类的属性和方法,如下:

1. 创建用户类User,定义类的属性(name,score)和类的方法(showFist())

2. 创建计算机类Computer,定义类的属性(name,score)和类的方法(showFist())

3. 实现计算机随机出拳

4. 创建游戏类Game,定义类的属性(甲方玩家、乙方玩家、对战次数)

5. 编写初始化方法、游戏开始方法

1、编写用户类User

/**
* @author DOUBLEXI
* @date 2021/8/17 16:45
* @description
*/
/**
* 用户类User
* @param name 用户名
* @param score 用户得分
*/
class User(var name: String, var score: Int) {
var draw: Int = 0 // 平局数
var defeat: Int = 0 // 败局数
var victory: Int = 0 // 胜局数 // 让用户自己出拳,输入1.剪刀 2.石头 3.布
def showFist(): Int = {
var fist = scala.io.StdIn.readInt()
while (fist != 1 && fist != 2 && fist != 3) {
println("输入不合法,请重新输入!!!")
fist = scala.io.StdIn.readInt()
}
return fist
} }

2、编写电脑类Computer

/**
* @author DOUBLEXI
* @date 2021/8/17 17:09
* @description
*/
/**
* 电脑类
* @param name 电脑名字
* @param score 电脑得分
*/
class Computer(var name: String, var score: Int) {
var draw: Int = 0 // 电脑平局数
var defeat: Int = 0 // 电脑败局数
var victory: Int = 0 // 电脑胜局数 /**
* 随机出拳,1-3
* @return 返回一个1-3的数字
*/
def showFist(): Int = {
scala.util.Random.nextInt(3) + 1
} }

3、编写游戏类Game

/**
* @author DOUBLEXI
* @date 2021/8/17 17:11
* @description
*/
/**
* 游戏类
*/
class Game {
var user: User = _ // 定义玩家
var computer: Computer = _ // 定义电脑
var battleNum: Int = _ // 定义对战次数 /**
* 游戏初始化方法
*/
def gameInit(): Unit = {
val motd =
"""
------------------欢迎进入游戏世界-----------------
**************************************
**************猜拳开始*****************
**************************************
""".stripMargin
println(motd) // 打印游戏欢迎信息
println("请选择对战角色:(1.刘备 2.关羽 3.张飞)") // 用户选择电脑的角色
var roleNum = scala.io.StdIn.readInt()
while (roleNum != 1 && roleNum != 2 && roleNum != 3) {
println("没有这个选项,请重新输入!")
roleNum = scala.io.StdIn.readInt()
}
val battleRole = roleNum match {
case 1 => "刘备"
case 2 => "关羽"
case 3 => "张飞"
}
println(s"你选择了与${battleRole}对战")
user = new User("游客", 0) // 初始化玩家信息
computer = new Computer(s"$battleRole", 0) // 初始化电脑信息
battleNum = 0 // 初始化对战信息
} /**
* 游戏主程,游戏开始方法
* 循环对战,直到输入n终止
*/
def startGame(): Unit = {
var isExist = false
var isStartNext: Char = 'y'
// 循环对战
while (!isExist) {
battleNum += 1; // 对战次数+1
// 玩家出拳
println("请出拳!1.剪刀 2.石头 3.布")
var userFist = user.showFist()
userFist match {
case 1 => println("你出拳:剪刀")
case 2 => println("你出拳:石头")
case 3 => println("你出拳:布")
}
// 电脑出拳
println(s"${computer.name}出拳!")
var computerFist = computer.showFist()
computerFist match {
case 1 => println(s"${computer.name}出拳:剪刀")
case 2 => println(s"${computer.name}出拳:石头")
case 3 => println(s"${computer.name}出拳:布")
}
// 调用judge方法,判断胜负
judge(userFist, computerFist)
// 根据用户输入判断是否开启下一轮游戏,n退出
println("是否开始下一轮(y / n)")
isStartNext = scala.io.StdIn.readChar()
while (isStartNext != 'n' && isStartNext != 'N' && isStartNext != 'Y' && isStartNext != 'y') {
println("您的输入不正确,请重新输入!")
isStartNext = scala.io.StdIn.readChar()
}
if (isStartNext =='n'|| isStartNext == 'N') isExist = true
}
println("退出游戏!")
// 打印得分成绩
echoResult
} /**
* 判断猜拳胜负
* @param userFist 用户出拳
* @param computerFist 电脑出拳
*/
def judge(userFist: Int, computerFist: Int): Unit = {
val judgeNum = userFist match {
case 1 => if (computerFist == 1) 0 else if (computerFist == 2) -1 else 1
case 2 => if (computerFist == 1) 1 else if (computerFist == 2) 0 else -1
case 3 => if (computerFist == 1) -1 else if (computerFist == 2) 1 else 0
} if (judgeNum == 0) {
println("结果:和局! 下次继续努力!")
user.score += 1
user.draw += 1
computer.score += 1
computer.draw += 1
} else if (judgeNum == 1) {
println("结果:恭喜,你赢啦!")
user.score += 2
user.victory += 1
computer.defeat += 1
} else {
println("结果:你输了,下次继续努力!")
user.defeat += 1
computer.victory += 1
}
} /**
* 打印得分成绩
*/
def echoResult(): Unit = {
println("---------------------------------------------------------")
println(s"${user.name} VS ${computer.name}")
println(s"对战次数${battleNum}次")
println()
println()
println("姓名\t等分\t胜局\t和局\t负局")
println(s"${user.name}\t${user.score}\t\t${user.victory}\t\t${user.draw}\t\t${user.defeat}")
println(s"${computer.name}\t${computer.score}\t\t${computer.victory}\t\t${computer.draw}\t\t${computer.defeat}")
}
} /**
* 游戏主程入口
*/
object Game {
def main(args: Array[String]): Unit = {
val game = new Game // 定义一个游戏对象
game.gameInit() // 游戏初始化
println("要开始么?y/n")
var isStart = scala.io.StdIn.readChar()
while (isStart != 'Y' && isStart != 'y' && isStart != 'n' && isStart != 'N') {
println("没有这个选项,请重新输入!")
isStart = scala.io.StdIn.readChar()
}
// 开始游戏
if (isStart == 'Y' || isStart == 'y') game.startGame
}
}

运行结果如下:

不合法输入:

打印得分:

第三题、用户位置时长统计

现有如下数据需要处理:

字段:用户ID,位置ID,开始时间,停留时长(分钟)

4行样例数据:

UserA,LocationA,8,60

UserA,LocationA,9,60

UserB,LocationB,10,60

UserB,LocationB,11,80

样例数据中的数据含义是:用户UserA,在LocationA位置,从8点开始,停留了60钟

处理要求:

1、对同一个用户,在同一个位置,连续的多条记录进行合并

2、合并原则:开始时间取最早时间,停留时长累计求和

答:算法如下:

1、定义一个样例类,用于存储每个用户的浏览数据

/**
* 定义一个样例类:装载用户时长数据
* @param userName 用户名
* @param location 用户位置
* @param startTime 用户开始浏览时间
* @param duration 用户本次浏览时长
*/
case class UserInfo(userName:String, location:String, startTime:Int, duration:Int)

2、在object主程序里,定义一个列表,用于存储各个用户的浏览信息。

// 定义一个列表,装载各个用户的时长数据
val userInfoList:List[UserInfo] = List(
UserInfo("UserA", "LocationA", 8, 60),
UserInfo("UserA", "LocationA", 9, 60),
UserInfo("UserB", "LocationB", 10, 60),
UserInfo("UserB", "LocationB", 11, 80)
)

3、接下来就是要对该用户浏览信息的列表数据做处理。

这里使用scala的算子来作数据处理。

因为要对同一个用户、同一个位置的多条记录做合并,所以用到groupby算子,把这两个字段提出来作为一个key,然后把数据做聚合

// 因为要对同一个用户,同一个位置的数据做合并,所以把这两个字段提出来,一起作为key聚合
val userMap = userInfoList.groupBy(t=>t.userName + ',' + t.location)
println(s"userMap: $userMap")

聚合后userMap数据为:

userMap: Map(UserB,LocationB -> List(UserInfo(UserB,LocationB,10,60), UserInfo(UserB,LocationB,11,80)), UserA,LocationA -> List(UserInfo(UserA,LocationA,8,60), UserInfo(UserA,LocationA,9,60)))

对聚合后的数据,按照startTime排序,方便后面取最早的时间

// 对聚合后的数据,按照startTime排序
val orderByUserMap = userMap.mapValues(t => t.sortBy(x=>x.startTime))
println(s"orderByUserMap: $orderByUserMap")

排完序后的数据为:

orderByUserMap: Map(UserB,LocationB -> List(UserInfo(UserB,LocationB,10,60), UserInfo(UserB,LocationB,11,80)), UserA,LocationA -> List(UserInfo(UserA,LocationA,8,60), UserInfo(UserA,LocationA,9,60)))

取得最早的时间,并统计浏览时长之和

var firstTime = 0

// totalMap: Map(UserB,LocationB -> 140, UserA,LocationA -> 120)
val totalMap = orderByUserMap.mapValues( t => {
// 将相同用户、相同位置下,最早的时间的作为firstTime
firstTime = t.head.startTime
// 时长字段相加,并作为totalMap的value返回
var sum = t.map(x=> x.duration).sum
sum
})
println(s"totalMap: $totalMap")

统计完的结果map如下:

totalMap: Map(UserB,LocationB -> 140, UserA,LocationA -> 120)

最后,再重新组合,打印最终结果数据:

// 重新组合数据,打印最终结果
/**
* datas就是totalMap的key,也就是(userName,location)
* sumTIme就是totalMap的value,也就是上面统计的sum
*/
totalMap.foreach{
case (datas, sumTime) => println(s"$datas,$firstTime,$sumTime")
}

最终结果如下:

UserB,LocationB,10,140
UserA,LocationA,8,120

合并总的程序如下:

/**
* @author DOUBLEXI
* @date 2021/8/18 15:16
* @description
*/ /**
* 定义一个样例类:装载用户时长数据
* @param userName 用户名
* @param location 用户位置
* @param startTime 用户开始浏览时间
* @param duration 用户本次浏览时长
*/
case class UserInfo(userName:String, location:String, startTime:Int, duration:Int) object UserLocationDurationCount {
def main(args: Array[String]): Unit = {
// 定义一个列表,装载各个用户的时长数据
val userInfoList:List[UserInfo] = List(
UserInfo("UserA", "LocationA", 8, 60),
UserInfo("UserA", "LocationA", 9, 60),
UserInfo("UserB", "LocationB", 10, 60),
UserInfo("UserB", "LocationB", 11, 80)
) // 因为要对同一个用户,同一个位置的数据做合并,所以把这两个字段提出来,一起作为key聚合
val userMap = userInfoList.groupBy(t=>t.userName + ',' + t.location)
println(s"userMap: $userMap")
// 对聚合后的数据,按照startTime排序
val orderByUserMap = userMap.mapValues(t => t.sortBy(x=>x.startTime))
println(s"orderByUserMap: $orderByUserMap") var firstTime = 0 // totalMap: Map(UserB,LocationB -> 140, UserA,LocationA -> 120)
val totalMap = orderByUserMap.mapValues( t => {
// 将相同用户、相同位置下,最早的时间的作为firstTime
firstTime = t.head.startTime
// 时长字段相加,并作为totalMap的value返回
var sum = t.map(x=> x.duration).sum
sum
})
println(s"totalMap: $totalMap") // 重新组合数据,打印最终结果
/**
* datas就是totalMap的key,也就是(userName,location)
* sumTIme就是totalMap的value,也就是上面统计的sum
*/
totalMap.foreach{
case (datas, sumTime) => println(s"$datas,$firstTime,$sumTime")
}
}
}

运行结果如下:

《Scala编程》课程作业的更多相关文章

  1. Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”

    Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...

  2. (升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)

    本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...

  3. coursea机器学习课程作业

    coursea机器学习课程作业 一 关于此课程 课程地址 图片来自网络 1.官网课程地址传送 2.如果访问官网速度较慢可以上 B站课程地址 机器学习是一门研究在非特定编程条件下让计算机采取行动的学科. ...

  4. THE LAST ONE!! 2017《面向对象程序设计》课程作业八

    THE LAST ONE!! 2017<面向对象程序设计>课程作业八 031602230 卢恺翔 GitHub传送门 题目描述 1.时间匆匆,本学期的博客作业就要结束了,是否有点不舍,是否 ...

  5. 《Linux编程大作业》

    一.要求 作业题目 Linux下的多进程/线程网络通信 作业目标 要求学生熟练掌握<Linux编程>课程中的知识点,包括Linux常用命令.bash脚本.编译和调试环境.读写文件.进程间通 ...

  6. 03.Scala编程实战

    Scala编程实战 1.    课程目标 1.1.  目标:使用Akka实现一个简易版的spark通信框架 2.    项目概述 2.1.   需求 Hivesql----------> sel ...

  7. 实验 2 Scala 编程初级实践

    实验 2 Scala 编程初级实践 一.实验目的 1.掌握 Scala 语言的基本语法.数据结构和控制结构: 2.掌握面向对象编程的基础知识,能够编写自定义类和特质: 3.掌握函数式编程的基础知识,能 ...

  8. 课程作业01:模仿JavaAppArguments.java示例,编写一个程序,此程序从命令行接收多个数字,求和之后输出结果。

    1.设计思想: 首先是从JavaAppArguments.java示例开始,此示例已打印参数,定义数字 之和和作为存储单位的整型,然后将输入参数的字符串转化为整型,之后求和即可. 2.程序流程图: 3 ...

  9. Scala 编程(一)Scala 编程总览

    Scala 简介 Scala 属于“可伸展语言”,源于它可以随使用者的需求而改变和成长.Scala 可以应用在很大范围的编程任务上,小到脚本大到建立系统均可以. Scala 跑在标准 Java 平台上 ...

  10. Scala编程进阶

    跳出循环语句的3种方法... 2 多维数组... 3 Java数组与Scala数组缓冲的隐式转换... 3 Java Map与Scala Map的隐式转换... 3 Tuple拉链操作... 4 内部 ...

随机推荐

  1. hdu 4521 小明序列(线段树,DP思想)

    题意: ①首先定义S为一个有序序列,S={ A1 , A2 , A3 , ... , An },n为元素个数 : ②然后定义Sub为S中取出的一个子序列,Sub={ Ai1 , Ai2 , Ai3 , ...

  2. JAVA笔记 **__Netbeans常用快捷键

    sout + Tab      生成输出语句 alt+shift+F 格式化代码 Alt+insert  插入代码(包括构造函数,setter和getter方法等) Ctrl+O或Ctrlt+单击 转 ...

  3. C++类的静态成员变量与静态成员函数

    1.类的静态成员变量 C++类的静态成员变量主要有以下特性: 1.静态成员变量需要类内定义,类外初始化 2.静态成员变量不依赖于类,静态成员变量属于全局区,不属于类的空间. 3.静态成员变量通过类名访 ...

  4. Markdown使用方式

    区块 区块引用在段落开头使用>,后面紧跟一个空格符号 > 区块引用 > XXX > XXX 高级技巧 HTML元素 居中  <center>XXX</cent ...

  5. 干货分享之spring框架源码分析02-(对象创建or生命周期)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea 之前分析了Spring读取xml文件的所有信息封装成beanDef ...

  6. Redis去重方法

    目录 1.基于 set 2.基于 bit 3.基于 HyperLogLog 4. 基于bloomfilter 这篇文章主要介绍了Redis实现唯一计数的3种方法分享,本文讲解了基于SET.基于 bit ...

  7. 【前端工具】nodejs+npm+vue 安装(windows)

    预备 先看看这几个是干嘛的,相互的关系是啥. nodejs是语言,类比到php. npm是个包管理,类比到composer. vue是个框架,类比到laravel. webpack是个打包工具. 先下 ...

  8. xmind 文件 打开后会在当前目录生成 configuration,p2和workspace目录,artifacts.xml文件 解决

    在xmind安装目录下的xmind.ini修改如下配置,为绝对路径

  9. CentOS8安装VirtualBox,并创建CentOS虚拟机

    安装VirtualBox 执行以下命令并启用VirtualBox和EPEL包仓库 [root@localhost~] dnf config-manager --add-repo=https://dow ...

  10. (五)MySQL函数

    5.1  常用函数 5.2  聚合函数(常用) 函数名称 描述 COUNT() 计数 SUM() 求和 AVG() 平均值 MAX() 最大值 MIN() 最小值 ....   ....   想查询一 ...