我正在解决一个类似的编程练习:
文件包含正整数和之间的等式列表,每行一个,每个以分号结尾,没有空格。这些平等可能是对的,也可能是错的。例如,请考虑以下文件:
2+3+12=9+8; 2+3+4=9; 22=3+4+5+10; 3+5+1=4+44;
编写一个以文件名作为第一个参数的程序,并输出正确行的比例。例如,给定上面的文件,程序应该输出0.75。
我在Scala中的解决方案如下,并且它可以工作,但我正在寻找一种在没有var的情况下重写它的方法。
import scala.io.Source
object Hello {
def main(args: Array[String]): Unit = {
var count: Int = 0
var correct: Int = 0
Source.fromFile(args(0)).getLines().zipWithIndex.foreach { case (line, i) =>
val regex = """^[1-9][0-9]*(\+[1-9][0-9]*)*=[1-9][0-9]*(\+[1-9][0-9]*)*;$""".r
regex findFirstIn line match {
case Some(_) =>
case None => throw new Exception("Error reading file, line " + i)
}
val sums = line.substring(0, line.length - 1).split('=').map {
_.split('+').map(Integer.parseInt).sum
}
count += 1
correct += (if (sums(0) == sums(1)) 1 else 0)
}
println("The ratio is " + correct.toFloat/count)
}
}
我试图把那个foreach变成一张地图,就像这样:
import scala.io.Source
object Hello {
def main(args: Array[String]): Unit = {
val file = Source.fromFile(args(0))
val correct = file.getLines().zipWithIndex.map({ case (line, i) =>
val regex = """^[1-9][0-9]*(\+[1-9][0-9]*)*=[1-9][0-9]*(\+[1-9][0-9]*)*;$""".r
regex findFirstIn line match {
case Some(_) =>
case None => throw new Exception("Error reading file, line " + i)
}
val sums = line.substring(0, line.length - 1).split('=').map {
_.split('+').map(Integer.parseInt).sum
}
return if (sums(0) == sums(1)) 1 else 0
}).sum
println("The ratio is " + correct/file.getLines().length)
}
}
编译器抱怨:
Warning:(15, 38) a pure expression does nothing in statement position; you may be omitting necessary parentheses
return if (sums(0) == sums(1)) 1 else 0
^
Warning:(15, 45) a pure expression does nothing in statement position; you may be omitting necessary parentheses
return if (sums(0) == sums(1)) 1 else 0
^
Warning:(15, 7) enclosing method main has result type Unit: return value discarded
return if (sums(0) == sums(1)) 1 else 0
^
Error:(16, 8) ambiguous implicit values:
both object BigIntIsIntegral in object Numeric of type scala.math.Numeric.BigIntIsIntegral.type
and object ShortIsIntegral in object Numeric of type scala.math.Numeric.ShortIsIntegral.type
match expected type Numeric[B]
}).sum
^
Error:(16, 8) could not find implicit value for parameter num: Numeric[B]
}).sum
^
Error:(16, 8) not enough arguments for method sum: (implicit num: Numeric[B])B.
Unspecified value parameter num.
}).sum
^
答案 0 :(得分:5)
您可以定义两个案例类来简化您的任务:
case class Equation(left:Sum,right:Sum) {
// to check if both sides of equation are equal
def isCorrect = left.sum == right.sum
}
object Equation {
// a pattern to extract left and right part of the equation
val equationPattern = "([0-9\\+]+)=([0-9\\+]+);".r
// apply method for building equation from string
def apply(line:String) = line match {
// building new equation, but use Sum for left/right side parsing
case equationPattern(left,right) => new Equation(Sum(left), Sum(right))
case _ => throw new IllegalArgumentException("cannot parse equation")
}
}
Equation
类用于解析和分析您的等式,但它使用嵌套的案例类Sum
来解析等式的左侧或右侧部分。
case class Sum(elements:List[Int]) {
// just sum all elements in this equation side
def sum:Int = elements.sum
}
object Sum {
// construct Sum from a String like "1+2+3+4"
def apply(line:String) = new Sum(line.split("\\+").map(_.toInt).toList)
}
使用这些简单的案例类,我们可以轻松地解析和分析像你这样的方程式:
object Main {
def main(args: Array[String]): Unit = {
println(Equation("1+2=3+4;").isCorrect) // prints 'false'
println(Equation("1+2+4=3+4;").isCorrect) // prints 'true'
}
}