在Kotlin中重复字符串n次
我想创建一个在Kotlin中重复字符串n次,kotlin,Kotlin,我想创建一个字符串,它将包含一个*符号n次。 我只是这样看: val s = "" val n = 100 for (j in 0 until n) { s += "*" } 但是它看起来很难看,而且它的时间复杂度为O(n^2)。Kotlin中有没有一种方法可以在不使用时间复杂度更好的循环的情况下实现这一点?StringBuilder将改进: 内置扩展以一种高效的方式实现了这一点,请参阅源代码 当然,这仍然需要O(n)个步骤来创建字符串。然而,使用这种内置的stdlib函数有其优点:它
字符串
,它将包含一个*
符号n
次。
我只是这样看:
val s = ""
val n = 100
for (j in 0 until n) {
s += "*"
}
但是它看起来很难看,而且它的时间复杂度为O(n^2)。Kotlin中有没有一种方法可以在不使用时间复杂度更好的循环的情况下实现这一点?
StringBuilder
将改进:
内置扩展以一种高效的方式实现了这一点,请参阅源代码
当然,这仍然需要O(n)个步骤来创建字符串。然而,使用这种内置的stdlib函数有其优点:它跨平台、易于阅读,并且如果有更高效的解决方案,随着时间的推移,它的性能可以得到提高。编译器或运行时可能会对其中的循环进行优化。CharSequence.repeat的另一种替代方法是带有init函数的Charray:
CharArray(N, {i -> '*'}).joinToString(separator="")
此解决方案的优点是可以定义前缀、后缀和分隔符 感谢和,我们可以写:
val sb = StringBuilder().apply{
repeat(100) {
append("*")
}
}
但这是一个简单的方法。看一个函数。它具有O(logn)复杂度
对于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)
}
}
对于字符串
:
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())
您可以重载
*
操作符,将其映射到现有的:
如果需要分隔符,此列表中的初始值设定项函数非常有用:
val str: String = List(100) { "*" }.joinToString(",")
这实际上是O(n²),因为
s+=“*”
在添加了一个“*”后重新创建了整个字符串(长度1到n)。我更正了这个问题,感谢使用val s=StringBuilder(n)
来解决性能问题是的,它更好,谢谢,但它仍然是循环,仍然是O(n)O(n)O(n)比原来的O(n^2)好,但为什么是n^2?只有一个LoopString是不可变的,因此n^2可以在每次连接时复制结果。您不必实例化StringBuilder,而是这样做:val result=buildString{(0..100)。forEach{append(“*”)}看起来不错,谢谢!似乎没有办法比O(n)更快,你认为呢?如果你看Java的同一个问题(或例如),所有的事情似乎都涉及到在字符串/数组的长度上循环一次。@Rainmaker没有办法在小于O(n)的时间内将n个字符串加在一起。您将始终需要至少访问每个字符串一次。
// 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())
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)
}
val str: String = List(100) { "*" }.joinToString(",")