【问题标题】:Buiding a stack in a map在地图中构建堆栈
【发布时间】:2011-05-21 01:47:17
【问题描述】:

我有一个如下所示的字符串:

 "7-6-4-1"

 "7"

 ""

即用-分隔的一组数字。可能有零个或多个数字。

我想返回一个堆栈,其中包含按该顺序推送的数字(即第一个示例中,首先推送 7 和 1 ast)

如果我只是想返回一个列表,我可以去str.split("-").map{_.toInt}(尽管这不适用于空字符串)/

虽然没有 toStack 可以转换为 Stack。所以目前,我有

  {
    val s = new Stack[Int]; 
    if (x.nonEmpty)
        x.split('-').foreach {
    y => s.push(y.toInt)
      }
   s
   }

这很有效,但很丑陋。我错过了什么?

编辑:感谢所有响应者,我从这次讨论中学到了很多

【问题讨论】:

    标签: string scala stack split scala-2.8


    【解决方案1】:
    (Stack[Int]() /: (if(x.isEmpty) Array.empty else x.split("-")))(
                      (stack, value) => 
                          stack.push(value toInt))
    

    【讨论】:

    • 谢谢。是 X 可以为空,而不是拆分后的字符串?你能解释一下吗? :)
    • @Paul foldLeft 用于使用来自拆分字符串的值递归填充新的空堆栈。
    【解决方案2】:
    Stack(x.split("-").map(_.toInt).reverse: _*)
    

    这里的技巧是将您从 split 中获得的数组传递给 Stack 伴随对象构建器。默认情况下,项目与数组的顺序相同,因此您必须先反转数组。

    请注意“将其视为一个列表,而不是单个项目”注释,: _*


    编辑:如果您不想单独捕获空字符串大小写,像这样(将底部用于可变堆栈,顶部用于不可变堆栈):

    if (x.isEmpty) Stack() else Stack(x.split("-").map(_.toInt).reverse: _*)
    if (x.isEmpty) Stack[Int]() else Stack(x.split("-").map(_.toInt).reverse: _*)
    

    然后你可以过滤掉空字符串:

    Stack(x.split("-").filterNot(_.isEmpty).map(_.toInt).reverse: _*)
    

    它还将为您“帮助”处理7-9----2-2-4 之类的事情(它会提供Stack(4,2,2,9,7))。

    如果你想处理更卑鄙的格式错误,你可以

    val guard = scala.util.control.Exception.catching[Int](classOf[NumberFormatException])
    Stack(x.split("-").flatMap(x => guard.opt(x.toInt)).reverse: _*)
    

    只返回那些实际可以解析的项目。

    【讨论】:

    • 谢谢。我还需要对 x 进行非空检查吗?
    • @Paul 是的,不存在非空检查
    • x => {Stack(x.split("-").collect{case x if x.nonEmpty => x.toInt}.reverse: _*)} 位。似乎涵盖了非空情况:)
    • 是的。适用于我的用例。在检查第一个 x 是否为空时,我无法弄清楚如何创建返回一个空的 Stack[Int](不幸的是,我的 Scala 仍处于“半随机更改内容直到它工作”级别,我找到了编译器类型问题的错误不透明)
    • @Paul:它会在每次迭代时检查初始字符串是否为空,而不是在开始时只检查一次。
    【解决方案3】:

    不要忘记方便的breakOut,它的性能比col: _* 稍好(参见Daniel's excellent explanation

    这里与 Rex Kerr 的 .filterNot(_.isEmpty) 解决方案一起使用:

    import scala.collection.immutable.Stack
    import scala.collection.breakOut
    
    object StackFromString {
    
      def stackFromString(str: String): Stack[Int] =
        str.split("-").filterNot(_.isEmpty)
          .reverse.map(_.toInt)(breakOut)
    
      def main(args: Array[String]): Unit = {
        println(stackFromString("7-6-4-1"))
        println(stackFromString("7"))
        println(stackFromString(""))
      }
    }
    

    将输出:

    Stack(1, 4, 6, 7)
    Stack(7)
    Stack()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多