实验 2 Scala 编程初级实践

image

// 在 spark-shell 提示符下直接粘贴即可
import scala.io.StdIn

val q = StdIn.readLine("请输入 q: ").trim.toDouble

var n   = 1
var sn  = 0.0
var term = 0.0

while (sn < q) {
  term = (n + 1).toDouble / n
  sn  += term
  n   += 1
}

println(f"Sn=$sn%.6f")

image

// ========= 1. 基础定义(题目已给出,顺手修掉笔误) =========
case class Point(var x: Double, var y: Double) extends Drawable {
  def shift(deltaX: Double, deltaY: Double): Unit = { x += deltaX; y += deltaY }
  override def toString: String = s"($x,$y)"
}

trait Drawable {
  def draw(): Unit = println(this.toString)
}

// ========= 2. 抽象基类 =========
abstract class Shape(var pos: Point) extends Drawable {
  def moveTo(newPos: Point): Unit = { pos = newPos }
  def zoom(factor: Double): Unit
}

// ========= 3. 直线 =========
class Line(var p1: Point, var p2: Point) extends Shape(p1) with Drawable {

  /* 中点 */
  private def mid: Point =
    Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2)

  /* 以中点为基准缩放 factor 倍 */
  override def zoom(factor: Double): Unit = {
    val m = mid
    p1.x = m.x + (p1.x - m.x) * factor
    p1.y = m.y + (p1.y - m.y) * factor
    p2.x = m.x + (p2.x - m.x) * factor
    p2.y = m.y + (p2.y - m.y) * factor
  }

  /* 移动:保持向量不变,整体平移 */
  override def moveTo(newPos: Point): Unit = {
    val dx = newPos.x - p1.x
    val dy = newPos.y - p1.y
    p1.shift(dx, dy)
    p2.shift(dx, dy)
  }

  override def toString: String = s"Line: $p1--$p2"
  override def draw(): Unit = println(toString)
}

// ========= 4. 圆 =========
class Circle(center: Point, var radius: Double)
  extends Shape(center) with Drawable {

  override def zoom(factor: Double): Unit = radius *= factor

  override def toString: String = s"Circle center: $pos,R=$radius"
  override def draw(): Unit = println(toString)
}

// ========= 5. 入口 =========
object MyDraw {
  def main(args: Array[String]): Unit = {
    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
  }
}

// ========= 6. 在 spark-shell 里跑起来 =========
MyDraw.main(Array.empty)

image

object GradeStatistics {

  private case class Student(id: String, gender: String, scores: Map[String, Double])

  // 从字符串解析数据
  private def parseData(data: String): (List[Student], List[String]) = {
    val lines = data.linesIterator.map(_.trim).filter(_.nonEmpty).toList
    if (lines.length < 2) return (Nil, Nil)

    // 解析表头
    val header = lines.head.split("\\s+").toList
    val courses = header.drop(2)

    // 解析学生数据
    val students = lines.tail.map { line =>
      val fields = line.split("\\s+")
      val id = fields(0)
      val gender = fields(1)
      val scores = (courses zip fields.drop(2).map(_.toDouble)).toMap
      Student(id, gender, scores)
    }

    (students, courses)
  }

  // 统计单个组
  private def calculateStats(students: List[Student], courses: List[String]):
  Map[String, (Double, Double, Double)] = {

    courses.map { course =>
      val scores = students.map(_.scores(course))
      val avg = scores.sum / scores.size
      val min = scores.min
      val max = scores.max
      course -> (avg, min, max)
    }.toMap
  }

  // 打印统计结果
  private def printStats(title: String, stats: Map[String, (Double, Double, Double)]): Unit = {
    println(title)
    println("course    average   min   max")
    stats.foreach { case (course, (avg, min, max)) =>
      println(f"$course:     $avg%5.2f   $min%5.2f   $max%5.2f")
    }
    println()
  }

  // 主处理函数
  def analyze(data: String): Unit = {
    val (students, courses) = parseData(data)

    if (students.isEmpty) {
      println("没有学生数据")
      return
    }

    println(s"共读取 ${students.size} 名学生数据")
    println(s"课程:${courses.mkString(", ")}")
    println("-" * 40)

    // 所有学生统计
    val overallStats = calculateStats(students, courses)
    printStats("所有学生成绩统计:", overallStats)

    // 男生统计
    val maleStats = calculateStats(students.filter(_.gender == "male"), courses)
    printStats("男生成绩统计:", maleStats)

    // 女生统计
    val femaleStats = calculateStats(students.filter(_.gender == "female"), courses)
    printStats("女生成绩统计:", femaleStats)
  }
}

// 测试主程序
object Test {
  def main(args: Array[String]): Unit = {
    println("=== 学生成绩统计分析 ===\n")

    // 测试样例1
    println("测试样例1:")
    val data1 =
      """Id  gender  Math    English   Physics
        |301610    male   80      64        78
        |301611  female   65      87        58
        |301612  female   44      71        77
        |301613  female   66      71        91
        |301614  female   70      71       100
        |301615    male   72      77        72
        |301616  female   73      81        75
        |301617  female   69      77        75
        |301618    male   73      61        65
        |301619    male   74      69        68
        |301620    male   76      62        76
        |301621    male   73      69        91
        |301622    male   55      69        61
        |301623    male   50      58        75
        |301624  female   63      83        93
        |301625    male   72      54       100
        |301626    male   76      66        73
        |301627    male   82      87        79
        |301628  female   62      80        54
        |301629    male   89      77        72""".stripMargin

    GradeStatistics.analyze(data1)

    println("=" * 60)

    // 测试样例2
    println("测试样例2:")
    val data2 =
      """Id  gender  Math    English   Physics  Science
        |301610    male   72   39     74   93
        |301611    male   75   85     93   26
        |301612  female   85   79     91   57
        |301613  female   63   89     61   62
        |301614    male   72   63     58   64
        |301615    male   99   82     70   31
        |301616  female  100   81     63   72
        |301617    male   74  100     81   59
        |301618  female   68   72     63  100
        |301619    male   63   39     59   87
        |301620  female   84   88     48   48
        |301621    male   71   88     92   46
        |301622    male   82   49     66   78
        |301623    male   63   80     83   88
        |301624  female   86   80     56   69
        |301625    male   76   69     86   49
        |301626    male   91   59     93   51
        |301627  female   92   76     79  100
        |301628    male   79   89     78   57
        |301629    male   85   74     78   80""".stripMargin

    GradeStatistics.analyze(data2)
  }
}
posted @ 2026-01-20 20:43  茆伟昊  阅读(0)  评论(0)    收藏  举报