这句话是什么“while(a [i] - != 0)”?

时间:2013-07-02 11:01:45

标签: c++ performance sorting while-loop

以下是用于按非递减顺序对数字进行排序的代码:

#include<stdio.h>
#include<stdlib.h>
# define size 1000001
static int a[size];
int main()
{
  int t, k, i;
  scanf("%d", &t);
  for(i = 0; i < t; i++)
  {
    scanf("%d", &k);
    a[k] += 1;
  }
  for(i = 0; i < 1000001; i++)
  {
    while(a[i]-- != 0)
      printf("%d\n", i);
  }
  return 0;
}

如果有人能够向我解释代码,那将是非常有帮助的。我已经完成了代码,我不知道如何对数字进行排序。在任何地方都没有进行交换,但它仍然适用于c ++编辑器。

6 个答案:

答案 0 :(得分:2)

这个程序不会在数学意义上对数字进行排序,但这并不重要,因为它会给你一种幻觉。

该程序要求t,这将更好地命名为numberOfValues ...您将输入的值的数量。

数组a[size]可以被认为是size值桶。在您的程序中,这些buckets只是计数器。每个桶都有一个0到0的数字。输入值5后,存储区a[5]的计数会增加。这一直持续到所有存储桶都设置完毕。

程序然后通过桶工作。大部分存储桶都是空的,但当存储桶非零时(while a[i] != 0 - 暂时忽略丢失的--),存储桶需要同时“清空”,其内容需要加以考虑。存储桶a[i]包含i个元素的计数,因此循环打印出排序中下一个值为i的值,同时还会减少计数(a[i]--)。这一直持续到存储桶为空(== 0)并且程序移动到下一个存储桶。

最终所有的存储桶都已清空,排序已完成。

答案 1 :(得分:1)

代码不错,但空间复杂度高。

这部分代码

for(i = 0; i < t; i++)
  {
    scanf("%d", &k);
    a[k] += 1;
  }

存储输入数字的频率(有点像散列)

如果我输入了 5 4 2 4 2

然后

a[5] =1 
a[4] =2
a[2] =2

其他都为零

所以如果你想在数组中找到“n”的频率,那么只需打印 a[n]


现在来回答你的问题

此代码如何对数字进行排序?

while(a[i]--!=0) 有什么用?

回答第一个问题:

我们从 0 到 1000001 在奥德所以如果输入 4 2 5 6

当循环从 0 到 100001 时,它首先检查 a[2] !=0 然后 a[4] 然后 a[5] 然后 a[6] 打印所有非零频率项。

因此根据检查 oder first 2 4 5 6 被打印

回答第二个问题:

为什么不是 while(a[i]!=0) 因为我只检查它是否非零,如果它的非零允许打印数字

但是说我输入了 4 3 2 4 2

然后输出应该打印 2 2 3 4 4

所以使用 while(a[i] --!=0) 它打印数字 a[i] 次说如果

a[4]=2 这意味着 4 出现了 2 次因此它应该打印 4 4 所以 while 循环作为 a[4] =2 运行两次

答案 2 :(得分:0)

每次打印时将变量a[i]递减到0为止

答案 3 :(得分:0)

没有交换因为不需要:数字不像往常一样存储,它使用一个巨大的数组来标记输入的数字:

如果添加数字200,则存储数组[200] = 1。如果再次添加200,则array [200] = 2。

然后,它按以下方式打印数组:想象你有[0,1,2,1,0,0 ...],所以有一个1,2两个,一个3 ... 所以它只显示1,2,2,3

答案 4 :(得分:0)

代码迭代数组a中的每个值。数组中的每个值a[i]都在while循环中迭代。 while(a[i]--!=0)检查a [i]的值是否为零。如果不是,则执行循环体。当控件进入循环体时,减小a [i]值。例如)如果a [i] = 6,则输出为:

5
4
3
2
1
0

答案 5 :(得分:0)

考虑i = 0; 然后a[i]--!=0将被执行,直到a[i]的值不会变为zero。当a[i]的值变为zero时,循环将终止并且下一次迭代{ {1}}循环将开始。