在Kotlin重复n次

时间:2018-01-25 15:21:21

标签: kotlin

我想创建一个string,其中包含*个符号n次。 我只是这样看:

val s = ""
val n = 100
for (j in 0 until n) {
    s += "*"
}

但它看起来很丑,而且时间复杂度为O(n ^ 2)。 Kotlin有没有办法在没有时间复杂度更高的循环的情况下做到这一点?

6 个答案:

答案 0 :(得分:10)

内置CharSequence.repeat扩展程序以有效的方式执行此操作,请参阅来源here

val str: String = "*".repeat(100)

当然,这仍然需要O(n)步骤来创建字符串。但是,使用这种内置的stdlib功能有其优点:它具有跨平台,易于阅读,并且如果有更高效的解决方案,可以随着时间的推移提高性能。无论如何,它内部的循环可能会被编译器或运行时优化。

答案 1 :(得分:2)

StringBuilder会改善memory footprint here

val sb = StringBuilder() 
val n = 100
for (j in 0 until n) {
  sb.append("*") 
}

答案 2 :(得分:1)

感谢Anton Sizikovhttps://kotlinlang.org/api/latest/jvm/stdlib/kotlin/repeat.html,我们可以写:

val sb = StringBuilder().apply{
    repeat(100) {
        append("*")
    }
}

但这是一种简单的方法。看一个power函数。具有O(log n)复杂度。

对于StringBuilder

private fun power(sb: StringBuilder, n: Int): StringBuilder =
    when {
        n == 0 -> StringBuilder("")
        n % 2 == 0 -> {
            val part = power(sb, n / 2)
            part.append(part)
        }
        else -> {
            val part = power(sb, n / 2)
            part.append(part).append(sb)
        }
    }

对于String

private fun pow(s: String, n: Int): String =
    when {
        n == 0 -> ""
        n % 2 == 0 -> pow(s, n / 2).repeat(2)
        else -> s + pow(s, n / 2).repeat(2)
    }

然后我们可以调用它们:

// 1.
val sb1 = StringBuilder().apply {
    repeat(100) {
        append("*")
    }
}

// 2.
val sb2 = power(StringBuilder("*"), 100)

// 3.
val s = power("*", 100)

println(sb1.toString())
println(s)
println(sb2.toString())

答案 3 :(得分:0)

CharSequence.repeat的替代方案是具有init函数的CharArray:

git apply -3

此解决方案的优点是您可以定义前缀,后缀和分隔符。

答案 4 :(得分:0)

您可以重载*运算符以将其映射到现有的repeat extension

public operator fun CharSequence.times(count: Int): String {
    return repeat(count)
}

fun main() {
    val s = "*" * 101
    println(s)
    println("Badger " * 12 + "Mushroom " * 2)
    println(s)
}

答案 5 :(得分:0)

如果您需要分隔符,列表中的此初始化函数很有帮助:

val str: String = List(100) { "*" }.joinToString(",")