如何使用 scala 链接自定义逻辑?

how do I chain the custom logic using scala?

我正在尝试使用 scala 实现多边形面积的计算

多边形面积参考https://www.mathopenref.com/coordpolygonarea.html

我能够成功编写代码,但我的要求是我希望最后一个 for 循环像其他地图逻辑一样链接在点变量中。地图不工作,因为列表的输出是 (N-1)

var lines=io.Source.stdin.getLines()
val nPoints= lines.next.toInt
var s=0
var points = lines.take(nPoints).toList map(_.split(" ")) map{case Array(e1,e2)=>(e1.toInt,e2.toInt)} 

 for(i <- 0 until points.length-1){    // want this for loop to be chained within points variable        
      s=s+(points(i)._1 * points(i+1)._2) - (points(i)._2 * points(i+1)._1)
    }



println(scala.math.abs(s/2.0))

我认为您正在寻找 slidingfoldLeftsliding(2) 会给你列表 List(i, i+1), List(i+1, i+2),... 然后你可以使用 foldLeft 进行计算:

val s = points.sliding(2).foldLeft(0){ 
  case (acc, (p1, p2)::(q1, q2)::Nil) => acc + p1*q2 - p2*q1 } 

如果我没看错公式,还有一个来自第一个和最后一个顶点的附加项(顺便说一句,看起来它在您的实现中丢失了)。您可以单独添加或重复列表末尾的第一个顶点。因此,合并到定义 points 的同一行并不那么容易。无论如何,我认为拆分成单独的语句更具可读性——一个定义 points,另一个在列表末尾重复 points 的第一个元素,然后折叠。

编辑以解决您的点有元组而不是列表的事实。我也默认 points 是一个列表,我相信。

怎么样(未测试)

val points2 = points.tail :+ points.head // shift list one to the left
val area = ((points zip points2)
    .map{case (p1, p2) => (p1._1 * p2._2) - (p2._1 * p1._2)}
    .fold(0)(_+_))/2