一、实验目的

1.掌握 Scala 语言的基本语法、数据结构和控制结构;
2.掌握面向对象编程的基础知识,能够编写自定义类和特质;
3.掌握函数式编程的基础知识,能够熟练定义匿名函数。熟悉 Scala 的容器类库的基本
层次结构,熟练使用常用的容器类进行数据;
4.熟练掌握 Scala 的 REPL 运行模式和编译运行方法。

二、实验平台

操作系统:Ubuntu16.04;
Spark 版本:2.1.0;
Hadoop 版本:2.7.1。

三、实验内容和要求

1. 计算级数

scala> import io.StdIn._
import io.StdIn._
scala> var Sn:Float = 0 
Sn: Float = 0.0
scala> var n:Float=1 
n: Float = 1.0
scala> println("please input q:") 
please input q:
scala> val q = readInt()
q: Int = 50

scala> while(Sn<q){ 
     | Sn+=(n+1)/n 
     | n+=1
     | }

scala> println(s"Sn=$Sn")
Sn=50.416695

2. 模拟图形绘制

case class Point(var x:Double,var y:Double) extends Drawable{
  def shift(deltaX:Double,deltaY:Double){x+=deltaX;y+=deltaY}
}
//特征
trait Drawable{
  def draw(){println(this.toString)}
}

//图形抽象类
abstract class Shape(var point: Point){
  var r=4.0
  def moveTo(point2: Point): Unit ={
    point=point2
  }
  // 抽象方法没有方法体
  def zoom(b:Double): Unit
  //圆形构造函数
  def this(cpoint: Point, cr:Double){
    //第一行必须要先调用默认的构造函数
    this(cpoint: Point)
    this.r=cr
  }
  //直线构造函数
  def this(lpoint:Point,lpoint2:Point){
    this(lpoint: Point)

  }
}
//圆形
class Circle(point: Point,R:Double) extends Shape(point: Point) with Drawable{
  r=R
  //重写,对图形放大,半径放大
  override def zoom(b:Double): Unit = {
    r = r * b
  }
  //重写,打印
  override def draw(): Unit ={
    var toString="Circle center:("+point.x+","+point.y+")\t"+"R="+r
    println(toString)
  }
  //重写,移动
  override def moveTo(point2: Point): Unit ={
    point.x=point2.x
    point.y=point2.y
  }
}
//直线
class Line(point: Point, point1: Point)extends Shape(point: Point) with Drawable{
  //重写,对图形放大
  override def zoom(b:Double): Unit = {
    var xmid=(point1.x+point.x)/2   //寻找中点坐标
    var ymid=(point1.y+point.y)/2
    point.x=xmid-(xmid-point.x)*b
    point.y=ymid-(ymid-point.y)*b
    point1.x=xmid+(point1.x-xmid)*b
    point1.y=ymid+(point1.y-ymid)*b
  }
  //重写,打印
  override def draw(): Unit ={
    var toString="Line:("+point.x+","+point.y+")--"+"("+point1.x+","+point1.y+")"
    println(toString)
  }
  //重写,移动
  override def moveTo(point2: Point): Unit ={
    point1.x=point1.x+point2.x-point.x
    point1.y=point1.y+point2.y-point.y
    point.x=point2.x
    point.y=point2.y
  }
}

object  MyDraw {
  def main(args: Array[String]) {
    val p=new Point(10,30)
    p.draw;

    val line1 = new Line(Point(0,0),Point(20,20))
    line1.draw
    line1.moveTo(Point(5,5)) //移动到一个新的点
    line1.draw
    line1.zoom(2) //放大两倍
    line1.draw
    
    val cir= new Circle(Point(10,10),5)
    cir.draw
    cir.moveTo(Point(30,20))
    cir.draw
    cir.zoom(0.5)
    cir.draw

  }
}

3.统计学生成绩

object scoreReport{ 
def main(args: Array[String]) { 
val inputFile = scala.io.Source.fromFile("test.txt") 
val originalData = 
inputFile.getLines.map{_.split("\\s+")} .toList 
val courseNames = originalData.head.drop(2) //获取第一行中的课程名 
val allStudents = originalData.tail // 去除第一行剩下的数据 
val courseNum = courseNames.length 

def statistc(lines:List[Array[String]])= { 

(for(i<- 2 to courseNum+1) yield { 
val temp = lines map {elem=>elem(i).toDouble} 
(temp.sum,temp.min,temp.max) 
}) map {case (total,min,max) => (total/lines.length,min,max) 
} // 最后一个 map 对 for 的结果进行修改,将总分转为平均分 
} 
// 输出结果函数 
def printResult(theresult:Seq[(Double,Double,Double)]){ 
// 遍历前调用 zip 方法将课程名容器和结果容器合并,合并结果为二元组容器 
(courseNames zip theresult) foreach { 
case (course,result)=> 
println(f"${course+":"}%-10s${result._1}%5.2f${result._2}%8.2f${result._3}%8.2f") 
} 
} 
// 分别调用两个函数统计全体学生并输出结果 
val allResult = statistc(allStudents) 
println("course average min max") 
printResult(allResult) 
//按性别划分为两个容器 
val (maleLines,femaleLines) = allStudents partition 
{_(1)=="male"} 
// 分别调用两个函数统计男学生并输出结果 
val maleResult = statistc(maleLines) 
println("course average min max") 
printResult(maleResult) 
// 分别调用两个函数统计男学生并输出结果 
val femaleResult = statistc(femaleLines) 
println("course average min max") 
printResult(femaleResult) 
} 
}

注意:这里应提前创建一个test.txt文件(默认在当前目录下创建)

03-14 11:39