编辑:鉴于后面的评论,我刚刚在一开始就提出了一些更新;将我的第一个文字留在底部.
所以,这里的核心方面是:
>你来到这里有一些问题X,但进一步询问告诉我们你实际上有一些问题Y要解决.这是你应该避免的事情:来到这里(或者当你自己解决问题时!)……那么你应该能够清楚地描述你已经或打算解决的问题.我不是在指点;只是表示你应该努力工作,以确保你明白你的真正问题是什么.
>从您询问我们如何处理数据中的重复数字这一事实也可以看出这一点.先生,先生:这是你的问题.我们不知道你为什么要数这些数字;我们不知道您的数据来自哪里;以及最终解决方案应如何处理重复条目.从这个意义上说,我只是改写第一段:你必须澄清你的要求.我们根本无法帮助这一部分.你看,你只提到了第二个数组中的重复项.那第一个呢?!
好的,关于你的问题.事实是:实际上,这只是“工作”.那里没有魔力.由于你有两个非常大的数组,处理未分类的数据是绝对禁止的.
因此,您首先要对两个数组进行排序.
然后迭代第一个数组,同时这样做,你也会查看第二个数组:
int indexWithinB = 0;
int counterForCurrentA = 0; // and actually ALL values from a before
for (int i=0; i
int currentA = a[i];
while (b[indexWithinB] < currentA) {
if (indexWithinB > 0) { // check required to avoid using 0-1
if (b[indexWithinB-1] != b[indexWithinB] { // avoid counting duplicates!
counterForCurrentA++;
}
}
indexWithinB++;
}
// while loop ended, this means: b[indexWithinB] == or > currentA
// this also means: counterForCurrentA ... should have the correct value
}
以上显然是伪代码.它旨在让你继续前进;而且很可能是那里存在微妙的错误.例如,正如安德烈亚斯指出的那样:上面需要加强以检查b.length.但这仍然是读者的锻炼.
这就是我对“正常工作”的意思:你只需坐下来,编写测试用例并优化我的草案算法,直到它为你完成工作.如果你发现它最初很难编程,那么拿一张纸,放下两个带数字的数组……然后手动计算.
最后提示:我建议编写大量的单元测试来测试你的算法(这样的东西非常适合单元测试);并确保你在这些测试中拥有所有的角落案例.在使用10 ^ 5元素阵列之前,您希望100%确定您的算法是正确的!
在这里,正如所承诺的那样,原来的答案是:
简单来说:迭代和计数是解决这个问题的最有效方法.因此,在您的上述情况下,省略排序可能会导致更快的总体执行时间.
那里的逻辑非常简单:为了知道小于x的数字的数量……你必须看看它们的全部.因此,您必须迭代整个数组(当该数组未排序时).
因此,鉴于您的初始陈述,除了迭代和计数之外别无其他.
当然,如果你需要多次计算……最初可能值得对数据进行排序.因为那时你可以使用binary search,并且在没有迭代所有数据的情况下获得计数.
并且:是什么让你认为用10 ^ 5元素迭代一个数组是一个问题?换句话说:您是否只是担心潜在的性能问题,或者您是否存在真正的性能问题?你看,在某些时候你可能不得不创建并填充该数组.这肯定比简单的for循环计数条目需要更多的时间(和资源).老实说:除非我们正在谈论一些小型嵌入式设备… 10 ^ 5个元素……即使在使用稍微过时的硬件时也几乎没有.
最后:当您担心运行时,简单的答案是:对输入数据进行切片,并使用2,4,8,…线程并行计算每个切片!但正如所说:在编写代码之前,我会做一些分析,确保你真的需要花费宝贵的开发时间.不解决假设的性能问题;专注于那些对您或您的用户真正重要的事情!