【问题标题】:Time Complexity of two loops两个循环的时间复杂度
【发布时间】:2012-07-30 18:22:58
【问题描述】:

我有两个用 C 编写的循环,第一个循环运行 n 次,其中 n 是输入字符串的长度。假设输入字符串为:*& 201 +ACD 3491 AASD 3

循环将扫描每个字符,如果遇到数字,它将计算数字的长度,并按该距离递增指针。因此,当指针p 指向2 并读取一个整数时,它将sscanf 数字(201)并将p 递增3。两个嵌套循环,其中一个运行N 次,另一个运行运行M 次的时间复杂度为O(N * M)

可以肯定地说我的算法中的时间复杂度也是O(N * M),其中M 是在特定迭代中扫描的位数?如果不是,那么整个事情的时间复杂度是多少?

编辑:

这是一些代码

char c;
while ((c = fgets(fp)) != EOF) {
    // scans characters, if a digit is encountered, get digit_length
    for (int i = 0; i < digit_length; i++)
        p++;
}

【问题讨论】:

  • 不想回答,因为我可能误解了你的解释。伪代码会好很多...
  • 我没有看到任何“M”循环发生 - 如果遇到数字,这只是一个持续操作,对吗?
  • @RobI,这正是我的想法。 sscanf 应该是一个恒定时间操作,因此该算法仍然是 O(1) 乘以 O(N) 循环,使其运行时间为 O(N)。
  • 然而,递增指针是在 for 循环中完成的。它看起来如下:for (int i = 0; i &lt; digit_length; i++) p++;
  • 请检查更新 -- 添加代码。

标签: c algorithm time-complexity


【解决方案1】:

如果您正在扫描以下所有数字:

201
01
1
3491
491
91
1
3

那么时间将是(最坏情况)O(N^2)。如果你以某种方式避免这种情况(你应该这样做),那么它将是 O(N)。

【讨论】:

  • 这是为什么呢? scanf 是常数时间。请检查我上面的编辑,我添加了一些代码并演示了嵌套循环的含义。
  • scanf 不是恒定时间。它的运行时间与它最终扫描的字符串的长度成正比。
  • 所以如果 sscanf 最终扫描 M 数字,那么复杂度是 O(N*M)。我上面的循环呢?请检查我添加的代码。
  • 我不能确定,因为你没有展示你是如何得到digit_length的,但假设这是你的代码看起来不错的线性时间 (O(N))。
  • int digit_length = log10(x) + 1 所以每隔一个外层循环迭代递增几次的内层for循环不考虑复杂性?
猜你喜欢
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 2021-10-07
相关资源
最近更新 更多