如果我漏掉了一些非常基础的东西,请原谅。
对于给定的晶格数组,其中晶格值表示其桶的最小值,最佳方法是如何分组值数组。
例如:
double[] lattice = { 2.3, 2.8, 4.1, 4.7 };
double[] values = { 2.35, 2.4, 2.6, 3, 3.8, 4.5, 5.0, 8.1 };
GroupByLattice(values, lattice);
这样,GroupByLattice返回的IGroupings看起来像:
2.3 : { 2.35, 2.4, 2.6 }
2.8 : { 3, 3.8 }
4.1 : { 4.5 }
4.7 : { 5.0, 8.1 }
编辑:
对于LINQ查询,我还不够熟悉,以下是我能想到的最好方法:
values.GroupBy( curr => lattice.First( lat => curr > lat) )
存在以下问题:
- 所有内容都会进入第一个桶 - 我能理解为什么(当然每个后续的情况都满足第一个桶),但我很难理解这些原地操作,以获得我实际想要的谓词。
- 我怀疑在LINQ查询内部使用另一个LINQ查询性能不佳。
事后解决方案和结果:
Dmitry Bychenko提供了一个很好的答案,我只是想为那些将来可能遇到这个答案的人提供一些跟进。我最初尝试解决的是:如何简化用于绘图的大型数据集?
首先,我的第一次尝试其实已经非常接近了。由于我的格子已经被排序,所以我只需要将.First( ... )
更改为.Last( ... )
即:
values.GroupBy( curr => lattice.Last( lat => curr > lat) )
虽然这很好,但我想知道Dmitry的解决方案能够表现得更好多少。我使用了一个随机的10000个双精度浮点数集合,并且间隔为0.25的格子进行了测试。(为了公平起见,我从Dmitry的解决方案中删除了.Select(...)
转换)
20次运行的平均值给出了结果:
Mine: 602ms
Dmitrys: 3ms
哇...太棒了!速度提高了200倍。200倍!我运行了几次并在调试器中检查才确信LINQ语句在时间戳之前被评估(可靠的.ToArray()
拯救了我)。我现在要说,任何想完成相同任务的人都应该绝对使用这种方法。
Last
等)为O(N)
时,二分查找仅为log(N)
。 - Dmitry Bychenko