Scala中的垂直直方图

时间:2014-08-14 06:50:36

标签: scala scala-collections

这是一个简单的编码练习。给定一个整数列表输出一个垂直直方图,显示每个数字在输入列表中的数量。如果lis为空,则输出一个空字符串。

List(5, 2, 3)

*  
*  
* *
***
*** 

我写了一个函数如下:

def hist(l: List[Int]) = if(l.isEmpty) "" 
  else Range(l.max, 0, -1).map(i => l.map(x => if(i <= x) "*" else " ").mkString)

你会如何解决这个问题?

P.S。忘了说你需要输出结果字符串

val r = hist(List(5, 2, 3))
r.foreach(s => println(s))

4 个答案:

答案 0 :(得分:4)

以下是我编写您实现的功能的方法:

def hist(xs: Seq[Int]): String =
  xs.map(i => Seq.fill(i)('*').padTo(xs.max, ' '))
    .transpose.reverse.map(_.mkString).mkString("\n")

Seq(5,2,3)的直方图看起来不像

 ** *
12345

答案 1 :(得分:2)

为了便于阅读,我会这样做:

def hist: List[Int] => IndexedSeq[List[String]] = {
  case Nil => Vector(List("")) 
  case xs  => Range(xs.max, 0, -1).map(i => xs.map(x => if(i <= x) "*" else " "))
}

我认为案件比if语句更容易理解和推理

运行它看起来像这样:

scala> hlist(List(5, 2, 3)).foreach(x => println(x.mkString))
*
*
* *
***
***

答案 2 :(得分:1)

空列表检查的返回类型与一般情况不同;考虑这个更新,

def hist(l: List[Int]): IndexedSeq[List[String]] = 
  if(l.isEmpty) 
    Vector(List("")) 
  else 
    Range(l.max, 0, -1).map(i => l.map(x => if (i <= x) "*" else " "))

然后是List(5, 2, 3)

hist(List(5, 2, 3))
res: Vector(List(*, " ", " "), List(*, " ", " "), List(*, " ", *), List(*, *, *), List(*, *, *))

等垂直打印,

hist(List(5, 2, 3)).foreach(v => println(v.mkString))

*  
*  
* *
***
***

<强>更新

val a = List(5, 2, 3),然后一个单行是这样的,

a.map(v => " " * (a.max - v) + "*" * v).transpose.foreach(x => println(x.mkString))

答案 3 :(得分:0)

有点冗长,但我相信Scala-way更多:

object Histogram {
  def hist(list:List[Int]):List[String] ={
    val max = list.max
    val matrix = list match{
      case Nil => Nil
      case _ =>{
        list map (l => "*" * l)
      }.map{
        s => s + (" " * (max - s.length))
      }
    }

    (0 to max-1).reverse map (
      i => (for (s <- matrix) yield s(i).toString).mkString
    ) toList
  }

  def main(args:Array[String]):Unit ={
    hist(List(5,2,3,7,4)).foreach(println)
  }
}

很少有好处: 1)您不需要使用l.isEmpty,因为Scala已经Nil

2)模式匹配总是有利于分解

3)您需要使用简单List[String]而不是IndexedSeq[List[String]],因此请使用IndexedSeq.toString方法进行转换