system.out.println 的时间复杂度
Posted
技术标签:
【中文标题】system.out.println 的时间复杂度【英文标题】:Time complexity of system.out.println 【发布时间】:2013-09-11 21:39:09 【问题描述】:在我的算法课程中,我被告知了不同的事情,我想知道我是否可以得到关于 Java 的 System.out.println() 命令的时间复杂度的明确答案。
例如,以下关于 N 的时间复杂度是多少?
String stringy = "";
while(stringy.length() < N)
System.out.println(stringy);
stringy += "X";
感谢您帮助新人!
【问题讨论】:
如果 N 大于 0,你就会得到一个无限循环。所以那将是 O(Infinity)。该功能将无法完成。 这不是无限循环。 这些操作的时间复杂度是O(n^2)。+=
是 O(N),你这样做 N 次。
我不是在乞求代表或任何东西,但你选择了一个非常错误的答案。它有两个非常不正确的假设,特别是它如何解决+=
。 No Idea For Name 的答案包含有关 System.out.println 实际复杂性的良好信息。
【参考方案1】:
此代码的时间复杂度为 O(N*N),因为它是一个打印 N 次的循环。我不知道你被告知了什么,但打印它的时间复杂度并不比 Java 中的 O(N) 差。
在您的代码中,您将“X”添加到每一行,因此您的打印将是:
X
XX
XXX
XXXX
XXXXX
XXXXXX
.
.
.
所以它的复杂度计算为Arithmetic progression,我们得到:
(1+N)*N/2=O(N^2)
要了解命令的工作原理,您可以阅读 here 或 here:
普遍认为 SOP 性能不佳。什么时候我们 深入分析,调用顺序就像 println -> print -> 写()+新线()。这个序列流是一个实现 Sun/Oracle JDK。 write() 和 newLine() 都包含一个同步的 堵塞。同步有一点开销,但更多的是 将字符添加到缓冲区和打印的成本很高。
当我们运行性能分析时,运行多个 SOP 和 记录时间,执行时间按比例增加。 当我们打印超过 50 个字符并打印时,性能会下降 超过 50,000 行。
这一切都取决于我们使用它的场景。不管是什么情况,做 不要使用 System.out.println 记录到标准输出。
【讨论】:
如果你承认循环运行了N次,并且打印是O(n)
操作,你怎么能说整个代码是O(n)
?
@corsiKa 你是绝对正确的,我早上的咖啡还没喝完,我要编辑这个并添加示例【参考方案2】:
时间复杂度告诉你你的算法每增加一个输入大小需要做多少工作,给定或取一些常数系数。
所以 O(2 N) 的上限复杂度等于复杂度 O(23587 N),因为此处找到的实际定义
http://en.wikipedia.org/wiki/Big_O_notation
表示系数可以是任意数字,无论多大,只要它在输入的大小方面是固定的。
因为你没有在循环中使用'N',你只是在一个字符串上添加一个字符,每次迭代的工作量等于你有多少次迭代 -> O(N)
如果你有 "stringy += stringy;"相反,它会是 O(N^2),因为每次迭代都会使你必须做的工作量翻倍
**注意
我假设 system.out.print 是一个原子语句,即它将所有字符打印为一个动作..如果它单独打印每个字符,那么它的 O(N^2)....
【讨论】:
即使没有 println 也是O(N^2)
,因为将字符添加到字符串也是线性运算。如果您按照您的建议添加了s += s
,并且 println 是常量(不是),那么整个代码将是O(n lg n)
。【参考方案3】:
我已经运行了一个基本的 Python 程序来检查 print 语句在 Python 中的时间复杂度,以了解可变数量的字符打印。代码如下 -
import time
def current_milli_time():
return round(time.time() * 1000)
=====================================
startTime1 = current_milli_time()
for i in range(10000):
print("a", end="")
endTime1 = current_milli_time()
=====================================
startTime2 = current_milli_time()
for i in range(10000):
print("ab", end="")
endTime2 = current_milli_time()
=====================================
startTime3 = current_milli_time()
for i in range(10000):
print("abc", end="")
endTime3 = current_milli_time()
=====================================
print("\nTime(ms) for first case: ", endTime1 - startTime1)
print("Time(ms) for second case: ", endTime2 - startTime2)
print("Time(ms) for second case: ", endTime3 - startTime3)
我们可以看到,在第一种情况下我们只打印了“a”,在第二种情况下我们打印了“ab”,在第三种情况下我们打印了“abc”,时间复杂度随着字符数线性增加。
因此,可以说对于每种语言,打印语句都需要 O(lengthOfString) 时间。
【讨论】:
【参考方案4】:这段代码的复杂度是O(n^2)
。它迭代循环 N 次,并且因为 System.out.println
必须打印每个字符,每次迭代打印 0 到 N 个字符,平均 N/2,你删除常数 N*N = N^2。以同样的方式,添加到字符串将导致整个字符串被复制(字符串在 Java 中是不可变的,因此任何更改都意味着您必须将整个字符串复制到一个新字符串中)。这是另一个线性操作。所以你有 n * (n/2 + n/2)
仍然是二次阶 - O(n^2)
。
String stringy = "";
while(stringy.length() < N) // will iterate N times
System.out.println(stringy); // has to print N letters
stringy += "X"; // has to copy N letters into a new string
【讨论】:
【参考方案5】:可以在这里找到一个很好的答案: http://www.quora.com/What-exactly-is-the-time-complexity-for-System-out-println-in-Java-O-1-or-O-N
主要思想是打印字符串实际上是将其复制到标准输出 - 我们知道字符串的副本是 o(n)。
第二部分说你可以尝试打印很多次: - 一个字符 - 一个非常大的字符串 你会看到时差! (如果打印是 o(1) 你不会)
【讨论】:
在答案中考虑链接的重要部分总是好的。【参考方案6】:System.out.println(stringy);
命令的时间复杂度???
你基本上是指上面代码sn-p的时间复杂度。看,时间复杂度与一种特定的代码或语言没有特别的关系,它基本上意味着理论上将花费多少时间行代码。这通常取决于两三件事:
输入的大小 多项式的次数(在求解多项式方程的情况下)现在在这部分代码中:
String stringy = "";
while(stringy.length() < N) // the loop will execute in order of N times
System.out.println(stringy);//println will execute in order of N times too as in printing each character
stringy += "X";
这显然取决于输入的大小,当然也就是字符串的长度。
首先,while循环执行的时间比N少一点(因为条件stringy.length() < N
使其<=
会使其贯穿字符串的全长),我们可以按N的顺序说,打印字符串将完成以 N 为顺序,因此整体代码的运行时间为 O(N^2)
【讨论】:
因为运行println
所需的时间也是线性的,所以您在线性循环中有一个线性运算,这会产生二次运行时间。以上是关于system.out.println 的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章
System.out.println 和 System.err.println 乱序
Scala 中的 println 与 System.out.println
使用 System.out.println() 的目的是啥 [关闭]