0

我有一个包含一些字符串的列表,只有当字符串中的字符长度<=某个限制时,我才想合并/连接字符串。

例如,我们有一个字符串列表:

val xs = List("This is a sentence in index0.", "This is a short sentence.", "This is a very very very loooooooooong sentence.", "This is another short sentence.", "Another one.", "The end!")

concat 限制为 60,这意味着我们必须在将字符串合并到下一个字符串之前查看字符串中字符的长度,并确保字符长度不超过 60。如果合并结果将超过 60,则不要合并并按原样获取元素/字符串,然后移动到下一个元素并尝试与下一个元素合并。

因此,如果我们采用上面的列表,

我们可以通过以下方式检查每个字符串中 char 的长度:

xs.map(_.length)
res: List[Int] = List(29, 25, 48, 31, 12, 8)

由此,我们只能连接索引 0 和 1 处的字符串,保留索引 2 并连接索引 3、4 和 5 处的字符串。生成的字符串列表现在应该如下所示:

val result = List("This is a sentence in index0.This is a short sentence.", "This is a very very very loooooooooong sentence.", "This is another short sentence.Another one.The end!")

假设您不知道列表中将有多少字符串,那么实现这一点的好方法是什么。

4

2 回答 2

3

我将这段代码拼凑在一起:

val xs = List(
  "This is a sentence in index0.",
  "This is a short sentence.",
  "This is a very very very loooooooooong sentence.",
  "This is another short sentence.",
  "Another one.",
  "The end!")

println(concatLimited(xs, 60))

def concatLimited(list: List[String], limit: Int): List[String] = {
  def concat(left: List[String], middle: String, right: List[String]): List[String] = {
    if (right.isEmpty) {
      left :+ middle
    }
    else {
      if (middle.length + right.head.length < limit) {
        concat(left, middle + right.head, right.tail)
      }
      else {
        concat(left :+ middle, right.head, right.tail)
      }
    }
  }

  if (list.isEmpty) List()
  else concat(List(), list.head, list.tail)
}

试试看!

它使用递归函数从列表的头部(此处:)中删除元素right并将它们收集在一个参数中middle,直到它超过您的大小,然后它附加middle到一个结果列表left并从一个新的开始middle,直到right为空。


我希望这有帮助。

于 2019-04-05T12:36:51.640 回答
0

在有效的字符串连接方面还有一点,这种实现concatenate不断寻找符合条件的索引范围(getNext告诉下一个子集的起始索引)并使用它们将它们相加StringBuilder并最终产生所有连接的字符串。

import scala.annotation.tailrec
import scala.collection.mutable.ListBuffer

object ListConcatenation extends App {
  val xs = List(
    "This is a sentence in index0.",
    "This is a short sentence.",
    "This is a very very very loooooooooong sentence.",
    "This is another short sentence.",
    "Another one.",
    "The end!")

  concatenate(xs, 60).foreach(println)

  def concatenate(values: List[String], limit: Int): List[String] = {
    def getNext(start: Int): Int = {
      @tailrec
      def getNext(sum: Int, index: Int): Int = {
        if (index >= values.length)
          index
        else {
          val next = sum + values(index).length

          if (next > limit)
            index
          else
            getNext(next, index + 1)
        }
      }

      getNext(0, start)
    }

    if (values == null || values.length <= 1)
      values
    else {
      val result = new ListBuffer[String]
      var head = 0

      do {
        val next = getNext(head)

        val builder = new StringBuilder

        (head until next)
          .map(values)
          .foreach(builder.append)

        result += builder.toString()

        head = next
      }
      while (head < values.length)

      result.toList
    }
  }
}
于 2019-04-05T13:02:55.590 回答