将字符串水平乘以 k* 次,垂直乘以 v* 次

Multiplying a string k*horizontally and v*times vertically

问题:

给你一个 n 行的字符串,每个子字符串的长度为 n 个字符。例如:

s = "abcd\nefgh\nijkl\nmnop"

字符串的 k 水平缩放包括将字符串的每个字符复制 k 次('\n' 除外)。

字符串的 v 垂直缩放包括将平方字符串的每个部分复制 v 次。

函数 scale(strng, k, v) 将执行 k 水平缩放和 v 垂直缩放。

示例:

a = "abcd\nefgh\nijkl\nmnop"
scale(a, 2, 3) --> "aabbccdd\naabbccdd\naabbccdd\neeffgghh\neeffgghh\neeffgghh\niijjkkll\niijjkkll\niijjkkll\nmmnnoopp\nmmnnoopp\nmmnnoopp".

我的问题是我已经编写了这个函数,而且就我的喜好而言它是完全正确的。

但是当我尝试 运行 程序通过测试时,有一个错误,因此我的程序没有通过任何测试。

我将测试附加到问题的底部,请帮忙。

object Kata {

    def scale(xs: String, k: Int, n: Int): String ={
      if(xs=="")
        ""
      else
      xs.split("\n")
   .map(_.map(_.toString*k).mkString("","","\n") * n)
   .mkString
      }



}
> Test Results:
 KataTest
 scale(abcd\nefgh\nijkl\nmnop, 2, 3) should return aabbccdd\naabbccdd\naabbccdd\neeffgghh\neeffgghh\neeffgghh\niijjkkll\niijjkkll\niijjkkll\nmmnnoopp\nmmnnoopp\nmmnnoopp
Test Failed

>"...pp
mmnnoopp
mmnnoopp[
]" was not equal to "...pp
mmnnoopp
mmnnoopp[]"
 Stack Trace
Completed in 24ms
 scale(, 5, 5) should return
 scale(Kj\nSH, 1, 2) should return Kj\nKj\nSH\nSH
Test Failed

>"Kj
Kj
SH
SH[
]" was not equal to "Kj
Kj
SH
SH[]"
 Stack Trace
 scale(lxnT\nqiut\nZZll\nFElq, 1, 2) should return lxnT\nlxnT\nqiut\nqiut\nZZll\nZZll\nFElq\nFElq
Test Failed

>"...
ZZll
ZZll
FElq
FElq[
]" was not equal to "...
ZZll
ZZll
FElq
FElq[]"
 Stack Trace
Completed in 1ms
 scale(YVjosW\nHGhKGZ\nLHNMLm\nJtcWCj\ngVtjyk\nOJBkOK, 2, 2) should return YYVVjjoossWW\nYYVVjjoossWW\nHHGGhhKKGGZZ\nHHGGhhKKGGZZ\nLLHHNNMMLLmm\nLLHHNNMMLLmm\nJJttccWWCCjj\nJJttccWWCCjj\nggVVttjjyykk\nggVVttjjyykk\nOOJJBBkkOOKK\nOOJJBBkkOOKK
Test Failed

>"...BkkOOKK
OOJJBBkkOOKK[
]" was not equal to "...BkkOOKK
OOJJBBkkOOKK[]"
 Stack Trace
Completed in 1ms

首先将行中的每个字母复制 k 次,然后将每行复制 v 次。

@ 
def scale(xs: String, k: Int, n: Int): String = xs.split("\n").flatMap(line => Array.fill(n)(line.flatMap(char => s"$char" * k))).mkString("\n") 
defined function scale

@ scale("abcd\nefgh\nijkl\nmnop", 2, 3) 
res11: String = """aabbccdd
aabbccdd
aabbccdd
eeffgghh
eeffgghh
eeffgghh
iijjkkll
iijjkkll
iijjkkll
mmnnoopp
mmnnoopp
mmnnoopp"""

总结:

 def scale(xs: String, k: Int, n: Int): String = xs
 .split("\n")
 .flatMap { line =>
   val repeatKTimes = line.flatMap(char => s"$char" * k) // each char is repeated k times
   Array.fill(n)(repeatKTimes)
 }.mkString("\n")

构建大字符串时,我建议使用 StringBuilder 以避免在正常字符串连接时产生额外的垃圾。

def scale(string: String, k: Int, v: Int): String = {
  import scala.collection.mutable.StringBuilder

  val textBuilder = new StringBuilder(capacity = string.length * k * v)
  val lineBuilder = new StringBuilder(capacity = k * 5)
  // The five above is just an stimated of how many characters there could be for a line on average.
  // The value does not have to be precise, but if it is just a little bit bigger than the real size, it would be more performant, without too much extra memory.
  // You can play with it.

  string.foreach {
    case '\n' =>
      val line = lineBuilder.append('\n').result()
      lineBuilder.clear()
      (0 until v).foreach { _ =>
        textBuilder.append(line)
      }

    case char =>
      (0 until k).foreach { _ =>
        lineBuilder.append(char)
      }
  }

  textBuilder.result()
}

scale("abcd\nefgh\nijkl\nmnop", 2, 3) 
res: String =
"""
aabbccdd
aabbccdd
aabbccdd
eeffgghh
eeffgghh
eeffgghh
iijjkkll
iijjkkll
iijjkkll
mmnnoopp
mmnnoopp
mmnnoopp
"""

注意:Pamu 的答案也在幕后使用 StringBuilders*mkString 都是根据它们实现的,因此两个答案都应该执行或多或少相似。我的只是试图避免中间 Arrays (但它使用中间 StringBuilders).