【问题标题】:How to split a string given a list of positions in Scala如何在给定Scala中的位置列表的情况下拆分字符串
【发布时间】:2011-11-28 17:35:26
【问题描述】:

您将如何为split(positions:List[Int], str:String):List[String] 编写一个功能 实现,它类似于splitAt,但将给定的字符串拆分为由给定列表组成的字符串list职位?

例如

  • split(List(1, 2), "abc") 返回List("a", "b", "c")
  • split(List(1), "abc") 返回List("a", "bc")
  • split(List(), "abc") 返回List("abc")

【问题讨论】:

  • 我会使用基于substring 而不是splitAt 的解决方案。前者将重用内存中的原始String,而后者会将字符串复制到新字符串中。提供的解决方案可以适应使用substring

标签: string scala collections


【解决方案1】:
def lsplit(pos: List[Int], str: String): List[String] = {
  val (rest, result) = pos.foldRight((str, List[String]())) {
    case (curr, (s, res)) =>
      val (rest, split) = s.splitAt(curr)
      (rest, split :: res)
  }
  rest :: result
}

【讨论】:

    【解决方案2】:

    类似这样的:

    def lsplit(pos: List[Int], s: String): List[String] = pos match {
      case x :: rest => s.substring(0,x) :: lsplit(rest.map(_ - x), s.substring(x))
      case Nil => List(s)
    }
    

    (公平警告:不是尾递归,因此会破坏大型列表的堆栈;由于重复重新映射索引和子字符串链而效率不高。您可以通过添加额外的参数和/或执行以下操作的内部方法来解决这些问题递归。)

    【讨论】:

    • 谢谢。我将为您的解决方案制作一个尾递归版本。
    • @Michael - 可能还想考虑添加一个startAt 索引,这样你就可以s.substring(startAt,x) :: lsplit(rest, s, startAt+x)(当然是在非尾递归版本中)。如果你这样做了,别忘了Nil 案例。
    【解决方案3】:

    怎么样....

    def lSplit( indices : List[Int], s : String) = (indices zip (indices.tail)) map { case (a,b) => s.substring(a,b) }
    
    scala> lSplit( List(0,4,6,8), "20131103")
    List[String] = List(2013, 11, 03)
    

    【讨论】:

      猜你喜欢
      • 2017-05-23
      • 2019-12-07
      • 2011-07-14
      • 1970-01-01
      • 2016-11-28
      • 2020-04-09
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多