【问题标题】:how to calculate frequency of this count algorithm statement blocks?如何计算此计数算法语句块的频率?
【发布时间】:2016-03-30 04:00:51
【问题描述】:

所以我从《算法第 4 版》一书中得到了这个计数算法,该算法在算法分析一章中使用,它们计算每个循环的频率、内部循环中的 if 语句以及开始时的声明。

他们将每个部分分为 A、B、C、D 和 E 部分。 他们说每个都有以下频率:

E  = X (depends on input)
D = (N^3)/6 - (N^2)/2 + N/3
C = (N^2)/2 - N/2
B = N
A = 1

我知道所有这些频率都来自部分和,但我不明白他们是如何得出每个答案的,如果有人能解释我为什么每个频率都是这样的,我将不胜感激。

public static int count(int[] a)
{
   int N = a.length; // Part A
   int cnt = 0;  // Part A

   for(int i = 0; i < N; i++)  //Part A
      for(int j = i+1; j < N; j++) // Part B
         for(int k = j+1; k < N; k++) // Part C
            if(a[i] + a[j] + a[k] == 0  // Part D
               cnt++; // Part E

   return cnt;
}

【问题讨论】:

    标签: algorithm for-loop code-complexity


    【解决方案1】:

    A 部分应该很明显:前三行执行一次。

    B 部分(外循环的主体)在外循环的每次迭代中执行一次,总共执行N 次。

    C 部分(第二个循环的主体)对外部循环的每次迭代执行 N - i - 1 次,其中 i 从 0 到 N-1 不等。当你加起来总和时(i=0..N-1){i}你得到N*(N-1)/2(N^2)/2 - N/2

    D 部分(第三个循环的主体)在第二个循环的每次迭代中执行 i - j - 1 次,其中 i 和以前一样从 0 到 N-1 变化,j 从 0 到 i - 1 变化.当你把这个加起来的时候,你会得到 D 的结果。

    E 部分(if 语句的主体)从 0(例如,所有 a[i] 值都是正数)到 D 次(例如,所有 a[i] 值都为零)执行。因此,您可以在 X 上设置界限,但如果不对输入做出一些假设,就不能说更多。

    【讨论】:

    • @TedHoop 你能解释一下你是如何计算第二个循环的部分总和并得出答案的吗?
    • @ravelinx - 你的意思是N*(N-1)/2?这是算术级数的经典总和。考虑 0 + 1 + 2 + ... + (N-1)。有N 术语,如果您从任一端(0 和(N-1);1 和(N-2);等)对数字进行分组,很容易看出每对的平均值正好是(N-1)/2。 (您应该说服自己,这对偶数和奇数 N 都有效。)因为有 N 值的平均值为 (N-1)/2,所以总数必须是 N*(N-1)/2。据说,这个推理就是卡尔·高斯9岁时建立算术级数公式的原因。
    • @TedHoop 是的,我了解 N*(N-1)/2 但我不了解的是 (N^3)/6 - (N^2)/2 + N/3 ,那个for循环不是内循环频率之和的和吗?
    • @ravelinx - 它来自评估 sum(i=0..N-1){S_i} 其中 S_i = sum(j=i+1..@ 987654352@-1){i - 1 - j}。 (i 的总和可以从 0 变为 N-2,因为 S_(N-1) = 0,对应于 i==N-1 的第三个循环体根本不执行。)j 的总和可以是使用前面的方法很容易用Ni 表示。 (请注意,i-1 是该总和的常数。)然后每个项可以在 i 上求和以产生最终结果。
    猜你喜欢
    • 2021-07-03
    • 1970-01-01
    • 2021-09-25
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多