Scala找到更优雅的方式

时间:2013-01-25 23:06:53

标签: scala functional-programming

我是Scala和函数式编程的新手。

我正在解决问题,你必须读取数字,然后是那个整数。之后,您应该计算所有整数中所有数字的总和。

这是我的代码

def sumDigits(line: String) = 
    line.foldLeft(0)(_ + _.toInt - '0'.toInt)

  def main(args: Array[String]) {
    val numberOfLines = Console.readInt
    val lines = for (i <- 1 to numberOfLines) yield Console.readLine   
    println(lines.foldLeft(0)( _ + sumDigits(_)))
  }

有更优雅或有效的方法吗?

4 个答案:

答案 0 :(得分:6)

使用sumDigits()

可以更轻松地实现

sum

def sumDigits(line: String) = line.map(_.asDigit).sum

第二个foldLeft()也可以替换为sum

lines.map(sumDigits).sum

这会将我们带到最终版本(注意没有main,而是使用扩展App):

object Main extends App {

    def sumDigits(line: String) = line.map(_.asDigit).sum

    val lines = for (_ <- 1 to Console.readInt) yield Console.readLine   
    println(lines.map(sumDigits).sum)

}

或者如果你真的想在一行中尽可能多地挤压内联sumDigits(不推荐):

lines.map(_.map(_.asDigit).sum).sum

答案 1 :(得分:4)

我喜欢紧凑的代码,所以我可能(如果我真的是为了简洁)

object Reads extends App {
  import Console._
  println( Seq.fill(readInt){readLine.map(_ - '0').sum}.sum )
}

设置内联行数并随时进行处理。但是,没有错误检查。您可以在.filter(_.isDigit)之后立即投放readLine至少丢弃非数字。您也可以def p[A](a: A) = { println(a); a }并将p中的读取包装起来,以便您可以看到键入的内容(默认情况下,某些平台上至少没有回显到屏幕)。

答案 2 :(得分:1)

单线答案:

 Iterator.continually(Console.readLine).take(Console.readInt).toList.flatten.map(_.asDigit).sum

答案 3 :(得分:0)

首先,你必须在line上进行某种解析来分解现有的十进制整数子字符串:

val numbers = "5 1 4 9 16 25"
val ints = numbers.split("\\s+").toList.map(_.toInt)

然后你想把第一个作为计数拉出来并保持其余的解码并求和:

val count :: numbers = ints

然后使用内置的sum方法:

val sum = numbers.sum

在REPL中一共:

scala> val numbers = "5 1 4 9 16 25"
numbers: String = 5 1 4 9 16 25

scala> val ints = numbers.split("\\s+").toList.map(_.toInt)
ints: List[Int] = List(5, 1, 4, 9, 16, 25)

scala> val count :: numbers = ints
count: Int = 5
numbers: List[Int] = List(1, 4, 9, 16, 25)

scala> val sum = numbers.sum
sum: Int = 55

如果您想使用前导数字计数,您可以验证它是否正确:

scala> assert(count == numbers.length)

由于断言通过,因此没有输出。