kotlin中Int.toString()的时间复杂性
我想知道kotlin中默认方法toString()的时间复杂度。是O(1)还是O(n)。我做了一些搜索,但没有找到任何答案。例如: 如果要将int数组转换为字符串,我使用了:kotlin中Int.toString()的时间复杂性,kotlin,time-complexity,Kotlin,Time Complexity,我想知道kotlin中默认方法toString()的时间复杂度。是O(1)还是O(n)。我做了一些搜索,但没有找到任何答案。例如: 如果要将int数组转换为字符串,我使用了: var s = "" array.forEach{ s+= it.toString() } 但是如果数组大小是10^4,我会得到TLE。如果我不使用toString(),那么我就不会得到TLE。我知道还有其他方法可以将Int数组转换为String。但我想知道kotlin中default toStr
var s = ""
array.forEach{
s+= it.toString()
}
但是如果数组大小是10^4,我会得到TLE。如果我不使用toString(),那么我就不会得到TLE。我知道还有其他方法可以将Int数组转换为String。但我想知道kotlin中default toString()方法的时间复杂性。TIAKotlin不保证产品的复杂性 它可能因对象而异;每个对象都必须实现它,因此它可能取决于对象的结构及其字符串表示。 在很多情况下,我猜它的长度很可能是线性的,但你不应该依赖它。 但这确实意味着使用短字符串表示的对象可能只需要很少的时间,因此不值得担心 特别是,对于
Int
s,字符串的大小很可能是线性的(因此与数字的对数成正比)。 但这对于任何现实世界的项目来说都不太重要
然而,可能重要的是构造的字符串对象的数量,因为这些对象占用内存,然后加速下一次垃圾收集。 (即使对于占用相同时间的垃圾收集器,不管“死”对象的数量如何,拥有大量临时对象也会使它们运行得更频繁。 在高通量系统中,这可能非常重要。)
这当然是问题中代码的一个问题,每次循环都会创建两个新的String
实例! 一个是调用toString()
的结果;另一个是将其附加到s
的结果。 (虽然前者总是很小,但后者每次都会不断增长,这使得空间需求呈二次型。) 这就是为什么在循环中进行字符串连接通常不是一个好主意
当然,String
是不可变的,但是它有一个可变的助手类。 因此使用StringBuilder
来累积结果,然后在末尾创建字符串(如果需要)几乎总是更好的:
val sb = StringBuilder()
array.forEach {
sb.append(it.toString())
}
val s = sb.toString()
在这种情况下,您可以做得更好,因为StringBuilder
重载append()
。 因此,您可以直接附加Int
,而无需创建中间字符串
:
val sb = StringBuilder()
array.forEach {
sb.append(it)
}
val s = sb.toString()
创建的唯一临时对象是StringBuilder
的内部数组;随着内容的不断增长,它将需要重新分配其数组来容纳它们。 如果可以估计最终结果的大小,则可以预先调整StringBuilder
的大小,以避免这种开销
但实际上,您可能根本不会使用循环;您可以使用,它可以为您完成所有这些:
val s = array.joinToString("")
这一版本更短、更简单、更容易阅读,而且可能与手工编码版本一样好用。 Kotlin有很多有用的扩展函数;很值得去熟悉他们
如果您需要自己尽可能高效地构造复杂的字符串表示,而不是使用toString()
来创建每个部分,每个相关类都可以有一个方法,该方法将StringBuilder
作为参数,并将其部分附加到该参数上。 这可以让您构建任意复杂的字符串,而不需要任何字符串实例 Kotlin不保证问题的复杂性
它可能因对象而异;每个对象都必须实现它,因此它可能取决于对象的结构及其字符串表示。 在很多情况下,我猜它的长度很可能是线性的,但你不应该依赖它。 但这确实意味着使用短字符串表示的对象可能只需要很少的时间,因此不值得担心
特别是,对于Int
s,字符串的大小很可能是线性的(因此与数字的对数成正比)。 但这对于任何现实世界的项目来说都不太重要
然而,可能重要的是构造的字符串对象的数量,因为这些对象占用内存,然后加速下一次垃圾收集。 (即使对于占用相同时间的垃圾收集器,不管“死”对象的数量如何,拥有大量临时对象也会使它们运行得更频繁。 在高通量系统中,这可能非常重要。)
这当然是问题中代码的一个问题,每次循环都会创建两个新的String
实例! 一个是调用toString()
的结果;另一个是将其附加到s
的结果。 (虽然前者总是很小,但后者每次都会不断增长,这使得空间需求呈二次型。) 这就是为什么在循环中进行字符串连接通常不是一个好主意
当然,String
是不可变的,但是它有一个可变的助手类。 因此使用StringBuilder
来累积结果,然后在末尾创建字符串(如果需要)几乎总是更好的:
val sb = StringBuilder()
array.forEach {
sb.append(it.toString())
}
val s = sb.toString()
在这种情况下,您可以做得更好,因为StringBuilder
重载append()
。 因此,您可以直接附加Int
,而无需创建中间字符串
:
val sb = StringBuilder()
array.forEach {
sb.append(it)
}
val s = sb.toString()
创建的唯一临时对象是StringBuilder
的内部数组;随着内容的不断增长,它会