• 寒假进度14spark实验 2 Scala 编程初级实践


    spark实验 2 Scala 编程初级实践

    实验内容和要求

    1. 计算级数

    请用脚本的方式编程计算并输出下列级数的前n项之和Sn,直到Sn刚好大于或等于q为止其中q为大于0的整数,其值通过键盘输入。 

    例如,若q的值为50.0,则输出应为:Sn=50.416695。请将源文件保存为exercise2-1.scala,在REPL模式下测试运行,测试样例:q=1时,Sn=2q=30时,Sn=30.891459q=50时,Sn=50.416695

    代码:

    object Test21 {
      def main(args: Array[String]): Unit = {
    
        import io.StdIn._
        var Sn: Float = 0
        var n: Float = 1
        println("please input q:")
        val q = readInt()
        while (Sn < q) {
          Sn += (n + 1) / n
          n += 1
        }
        println(s"Sn=$Sn")
    
      }
    
    }

    运行截图:

     

    2. 模拟图形绘制

    对于一个图形绘制程序,用下面的层次对各种实体进行抽象。定义一个Drawable的特质,其包括一个draw方法,默认实现为输出对象的字符串表示。定义一个Point类表示点,其混入了Drawable特质,并包含一个shift方法,用于移动点。所有图形实体的抽象类为Shape,其构造函数包括一个Point类型,表示图形的具体位置(具体意义对不同的具体图形不一样)。Shape类有一个具体方法moveTo和一个抽象方法zoom,其中moveTo将图形从当前位置移动到新的位置,各种具体图形的moveTo可能会有不一样的地方。zoom方法实现对图形的放缩,接受一个浮点型的放缩倍数参数,不同具体图形放缩实现不一样。继承Shape 类的具体图形类型包括直线类 Line 和圆类 CircleLine 类的第一个参数表示其位置,第二个参数表示另一个端点,Line 放缩的时候,其中点位置不变,长度按倍数放缩(注意,缩放时,其两个端点信息也改变了),另外,Linemove行为影响了另一个端点,需要对move 方法进行重载。Circle类第一个参数表示其圆心,也是其位置,另一个参数表示其半径,Circle缩放的时候,位置参数不变,半径按倍数缩放。另外直线类Line和圆类Circle都混入了Drawable特质,要求对 draw 进行重载实现,其中类Linedraw输出的信息样式为“Line:第一个端点的坐标--第二个端点的坐标)”,类Circledraw输出的信息样式为“Circle center:圆心坐标,R=半径”。如下的代码已经给出了DrawablePoint的定义,同时也给出了程序入口main函数的实现,请完成Shape类、Line类和Circle类的定义。

     

    编译运行程序,期望的输出结果如下:

     

     

    代码:

    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 location:Point)
    {
      //location 是 Shape 的一个可变字段
      def moveTo(newLocation:Point)
      {
        // 默认实现, 只是修改位置
        location = newLocation
      }
      def zoom(scale:Double)
    }
    class Line(beginPoint:Point,var endPoint:Point) extends
      Shape(beginPoint) with Drawable{
      override def draw()
      {
        println(s"Line:( ${location.x},${location.y})--(${endPoint.x},${endPoint.y})")
      }
      // 按指定格式重载 click
      override def moveTo(newLocation:Point)
      {
        endPoint.shift(newLocation.x -
          location.x,newLocation.y -
          location.y) //直线移动时,先移动另外一个端点
        location = newLocation //移动位置
      }
      override def zoom(scale:Double)
      {
        val midPoint = Point(
          (
            endPoint.x + location.x)/2,
          (
            endPoint.y +
              location.y)
            /2)
        //求出中点,并按中点进行缩放
        location.x = midPoint.x + scale * (location.x -
          midPoint.x)
        location.y = midPoint.y + scale * (location.y -midPoint.y)
        endPoint.x = midPoint.x + scale * (endPoint.x -
          midPoint.x)
        endPoint.y = midPoint.y + scale * (endPoint.y -midPoint.y)
      }
    }
    class Circle(center:Point,var radius:Double) extends Shape(center)
      with Drawable{
      override def draw()
      {
        //按指定格式重载 click
        println(s"Circle center: ( ,${location.y}), R=$radius")
      }
      override def zoom(scale:Double)
      {
        radius = radius*scale //对圆的缩放只用修改半径
      }
    }
    object Test22{
      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. 统计学生成绩

    学生的成绩清单格式如下所示,第一行为表头,各字段意思分别为学号、性别、课程名1、课程名2等,后面每一行代表一个学生的信息,各字段之间用空白符隔开

     

    给定任何一个如上格式的清单(不同清单里课程数量可能不一样),要求尽可能采用函数式编程,统计出各门课程的平均成绩,最低成绩,和最高成绩;另外还需按男女同学分开,分别统计各门课程的平均成绩,最低成绩,和最高成绩。

    测试样例 1 如下:

     

    样例 1 的统计结果输出为:

     

     

    测试样例 2

     

    样例 2 的统计结果为:

     

    代码:

    object Test23{
      def main(args:
               Array[String]
              )
      {
        // 假设数据文件在当前目录下
        val inputFile = scala.io.Source.fromFile("src/main/test.txt")
        //”\\s+“ 是字符串正则表达式, 将每行按空白字符(包括空格 / 制表符) 分开
        // 由于可能涉及多次遍历, 同 toList 将 Iterator 装为 List
        // originalData 的类型为 List[Array[String] ]
        val originalData =
          inputFile.getLines.map{_.split("\\s+")
          }
            .toList
        val courseNames = originalData.head.drop(2) //获取第一行中的课程名
        val allStudents = originalData.tail //去除第一行剩下的数据
        val courseNum = courseNames.length
        // 统计函数, 参数为需要常用统计的行
        // 用到了外部变量 courseNum , 属于闭包函数
        def statistc(lines:List[Array[String]]) = {
          // for 推导式, 对每门课程生成一个三元组, 分别表示总分, 最低分和最高分
          (
            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)
      }
    }

    运行截图:

     

  • 相关阅读:
    第19章 网络通信----网络程序设计基础
    第18章 多线程----线程同步
    第18章 多线程----线程的优先级
    一款基于jquery和css3的响应式二级导航菜单
    一款纯css3实现的颜色渐变按钮
    一款基于jquery的手风琴显示详情
    推荐10款纯css3实现的实用按钮
    一款纯css3实现的数字统计游戏
    一款基于jquery ui的动画提交表单
    一款纯css实现的漂亮导航
  • 原文地址:https://www.cnblogs.com/wangdayang/p/15802857.html
Copyright © 2020-2023  润新知