查找C中输入频率最高的数字的最佳(最快)方法?

查找C中输入频率最高的数字的最佳(最快)方法?,c,optimization,C,Optimization,嗯,我想这个标题基本上解释了我的疑问。我将有n个数字要读,这个n数字从1到x,其中x最多是105。最快的方法是什么(运行时间可能更短)来确定插入次数更多的数字?知道出现次数最多的数字会出现一半以上的次数 到目前为止,我所尝试的: //for (1<=x<=10⁵) int v[100000+1]; //multiple instances , ends when n = 0 while (scanf("%d", &n)&&n>0) { zero

嗯,我想这个标题基本上解释了我的疑问。我将有n个数字要读,这个n数字从1x,其中x最多是105。最快的方法是什么(运行时间可能更短)来确定插入次数更多的数字?知道出现次数最多的数字会出现一半以上的次数

到目前为止,我所尝试的:

//for (1<=x<=10⁵)
int v[100000+1];

//multiple instances , ends when n = 0
while (scanf("%d", &n)&&n>0) {
    zerofill(v);
    for (i=0; i<n; i++) {
        scanf("%d", &x);
        v[x]++;
        if (v[x]>n/2)
            i=n;
    }
    printf("%d\n", x);
}

//对于(1我认为您可以为读取的数量创建一个最大堆,并使用堆排序查找大于n/2的所有计数保留计数器数组的简单解决方案是
O(n)
你显然没有比这更好的了。接下来的战斗是关于常数的,这是很多细节的游戏,包括
n
x
的值,什么样的处理器,什么样的架构等等

另一方面,这似乎确实是一个“淘汰”问题,但该算法将需要两次数据传递和一个额外的条件,因此,在我所知道的计算机中,对于许多
n
x
值,它最有可能比计数器数组解慢

敲除解决方案的优点是不需要对值设置限制
x
,也不需要任何额外内存

如果你已经知道有一个绝对多数的值(你只需要找出这个值是什么),那么这就可以了(但是在内部循环中有两个条件):

  • 初始化
    count=0
  • 在所有元素上循环
  • 如果
    count
    0
    则设置
    champion=element
    count=1
  • 如果
    元素!=冠军
    减量
    计数
  • 其他增量<代码>计数
在循环结束时,如果存在这样一个值,则您的
champion
将是元素占绝对多数的值

但正如前面所说的,我希望有一个小问题

for (int i=0,n=size; i<n; i++) {
    if (++count[x[i]] > half) return x[i];
}
for(int i=0,n=size;i半)返回x[i];
}
要快一点

编辑
编辑之后,你似乎真的在寻找淘汰算法,但对于现代计算机来说,关心速度可能仍然是一个错误的问题(今天,即使是一块钉子大小的芯片,100000个元素也算不了什么)向量将意味着C++,而不是C。你可能需要重新标记你的问题来得到你需要的答案。添加代码,显示你所尝试的到目前为止,too@EliasVanOotegem对不起,我的意思是数组不是向量,数组在我的母语中是一个“vetor”。你是如何用“最少代码”来衡量“最快”的“挂钟最快,即使它意味着在组装中手工编码?"@templatetypedef所说的最快我的意思是它运行时间更短,很抱歉没有指出这一点。房间里的大象是
scanf
将比算法的其余部分占用更多的CPU。如果你担心运行时间,那么你需要优化IO,而不是算法。不知道我是否在说显而易见的事情,但它会是只有一个输入的wich出现了n/2次以上。另外,对不起,我认为我没有完全遵循您的逻辑。这也是我将使用的方法。我建议使用stl Library的std::priority_queue About
maximum heap
,您可以在这里参考,谢谢,已经解决了我的问题,但会考虑一下。是的,我知道ce确定一个值占绝对多数。你的解决方案看起来很好,我从来没有想过。我现在就试试看,谢谢!我需要关注速度,以便能够在给定的时间内解决问题,在特定的环境中运行,此练习是大学工作的一部分。你的计数器想法更快了虽然比我的数组算法更适合我的需要,非常感谢。现在想想绝对速度,你能指出解决这类问题的最快(候选)方法/算法吗?(不一定与C相关),我真的很喜欢这种优化的东西,学习汇编是我的下一个目标之一。