c# - 我正在尝试找到一种更好的方法来查找数组中第 n 个最稀有的元素
问题描述
说,
elements=5, 4, 2, 2, 1, 5, 4, 3, 3, 4, 4, 3, 5, 5, 5
return elements.GroupBy(x=>x).OrderBy(x=>x.Count()).Skip(n-1).FirstOrDefault().Key;
对于较大的数组,超出了内存限制。有一个更好的方法吗?
解决方案
更大是一个相对术语,但您可以尝试回到基础并计算自己。
var elements = new[] { 5, 4, 2, 2, 1, 5, 4, 3, 3, 4, 4, 3, 5, 5, 5 };
var counts = new Dictionary<int, int>(capacity: elements.Length); // Worst case capacity
for (int i = 0; i < elements.Length; i++)
{
counts.TryGetValue(elements[i], out var count);
counts[elements[i]] = ++count;
}
var n = 5;
var nthRarest = counts.OrderBy(x => x.Value).Skip(n - 1).FirstOrDefault();
Console.WriteLine($"'{nthRarest.Key}' with {nthRarest.Value}"); //'5' with 5
回复:@mjwills 的 TryGetValue 评论。
我使用的原始计数器ContainsKey
和@mjwills 建议TryGetValue
。以下是一些低质量的基准:
- 与 ContainsKey: '3' 与 99829 @ 00:00:00.0808146
- 使用 TryGetValue: '3' 使用 99829 @ 00:00:00.0594995
var elements = Enumerable.Range(0, 1_000_000).Select(i => r.Next(0,10)).ToArray();
var sw = Stopwatch.StartNew();
(...)
var elapsed = sw.Elapsed;
Console.WriteLine($"'{nthRarest.Key}' with {nthRarest.Value} @ {elapsed}");
老办法:
if (!counts.ContainsKey(elements[i]))
counts[elements[i]] = 1;
else
counts[elements[i]] += 1;
推荐阅读
- image - Pov-ray 中的 image_map 未按预期工作
- javascript - javascript通过lodash获取具有相同键的数组对象的平均值
- css - 如何将 MDC Web 的 Filled TextField 的高度设置为更小,但仍允许浮动标签正确浮动?
- javascript - WebExtensions:onConnect 的意义何在?onMessage 似乎是多余的
- angular - 如果发生错误异常,我如何计算执行重试运算符的次数
- generics - 将 trait 中方法的返回类型与实现该 trait 的类型绑定
- r - 如何从 ggplot2 中的汇总统计信息制作箱线图?
- javascript - 在 MS Edge 中使用 beforeunload 事件处理程序
- solr - 分面搜索 - 使用带有 AND / OR 连接的多个方面
- python - 如何在 Python 中使用 Beautifulsoup 获取嵌套标签的文本?