C# C语言中的简单LINQ问题#
我试图使用C# C语言中的简单LINQ问题#,c#,.net,linq,C#,.net,Linq,我试图使用LINQ返回出现次数最多的元素及其出现次数 例如: 我有一个字符串数组: string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" }; //... Some LINQ statement here //... 在这个数组中,查询将返回cherry作为出现的最大元素,返回3作为出现的次数。如果有必要,我也愿意将它们分为两个查询(即,第一个查询获取cherry,第二个查询返回3
LINQ
返回出现次数最多的元素及其出现次数
例如:
我有一个字符串数组:
string[] words = { "cherry", "apple", "blueberry", "cherry", "cherry", "blueberry" };
//...
Some LINQ statement here
//...
在这个数组中,查询将返回
cherry
作为出现的最大元素,返回3
作为出现的次数。如果有必要,我也愿意将它们分为两个查询(即,第一个查询获取cherry
,第二个查询返回3
的计数,这是我想到的第一件事(意味着可能有更有效的方法)
编辑:您想要姓名和计数试试这个:
如果我们不喜欢O(N logn)
:
var-topWordGroup=words.GroupBy(word=>word.Aggregate((当前,acc)=>current.Count()
目前提供的解决方案是O(n log n)
。这里有一个O(n)
解决方案:
var max = words.GroupBy(w => w)
.Select(g => new { Word = g.Key, Count = g.Count() })
.MaxBy(g => g.Count);
Console.WriteLine(
"The most frequent word is {0}, and its frequency is {1}.",
max.Word,
max.Count
);
var groups = words.GroupBy(x => x);
var max = groups.Max(x => x.Count());
var top = groups.First(y => y.Count() == max).Key;
这需要定义MaxBy
public static TSource MaxBy<TSource>(
this IEnumerable<TSource> source,
Func<TSource, IComparable> projectionToComparable
) {
using (var e = source.GetEnumerator()) {
if (!e.MoveNext()) {
throw new InvalidOperationException("Sequence is empty.");
}
TSource max = e.Current;
IComparable maxProjection = projectionToComparable(e.Current);
while (e.MoveNext()) {
IComparable currentProjection = projectionToComparable(e.Current);
if (currentProjection.CompareTo(maxProjection) > 0) {
max = e.Current;
maxProjection = currentProjection;
}
}
return max;
}
}
publicstatictsource-MaxBy(
这是一个数不清的来源,
Func投影
) {
使用(var e=source.GetEnumerator()){
如果(!e.MoveNext()){
抛出新的InvalidOperationException(“序列为空”);
}
t电源最大值=e.电流;
i可比较的最大投影=可比较的投影(如当前);
while(如MoveNext()){
IComparable currentProjection=projectionToComparable(当前);
如果(currentProjection.CompareTo(maxProjection)>0){
最大值=e.电流;
最大投影=当前投影;
}
}
返回最大值;
}
}
更简单的O(n)解决方案:
var max = words.GroupBy(w => w)
.Select(g => new { Word = g.Key, Count = g.Count() })
.MaxBy(g => g.Count);
Console.WriteLine(
"The most frequent word is {0}, and its frequency is {1}.",
max.Word,
max.Count
);
var groups = words.GroupBy(x => x);
var max = groups.Max(x => x.Count());
var top = groups.First(y => y.Count() == max).Key;
这里有一个非常快速的O(n)解,一行(!):
这是
O(n日志n)
当O(n)
是可能的:。这是O(n日志n)
O(n)时的O(n日志n)`有可能:。@Jason Ha!我们再次见面!你再次说得对。我忽略了使用Jon Skeet的Morelink什么是Jon的Morelink?我见过他的MiscUtil,但从来没有见过Morelink。对于添加的方法列表:MaxBy就是其中之一。嘿,只要看看他的MaxBy
的源代码就可以了。我觉得想出有效的方法很好我和Jon是同一个实现(和同一个名字!)。我想我今天就要结束了;除了从这里下来,我无处可去。谢谢linq(哈,双关语不好笑)。这是O(n log n)
whenO(n)
是可能的:。如果需要,您也可以用Aggregate
代替MaxBy
,尽管MaxBy
更好:var max=words.GroupBy(x=>x,(k,g)=>new{Word k,Count=g.Count())。聚合((a,x)=>(x.Count>a.Count)?x:a)
伙计们!GroupBy不是线性的。散列冲突的惩罚很小。我在编造这个,但它类似于O(n*loglogn)@JakubŠturc:排序在最坏的情况下可以降级为O(n^2)
,具体取决于使用的算法。但平均而言,它是O(n logn)
GroupBy
通常是O(n)
。
var max = words.GroupBy(w => w)
.Select(g => new { Word = g.Key, Count = g.Count() })
.MaxBy(g => g.Count);
Console.WriteLine(
"The most frequent word is {0}, and its frequency is {1}.",
max.Word,
max.Count
);
public static TSource MaxBy<TSource>(
this IEnumerable<TSource> source,
Func<TSource, IComparable> projectionToComparable
) {
using (var e = source.GetEnumerator()) {
if (!e.MoveNext()) {
throw new InvalidOperationException("Sequence is empty.");
}
TSource max = e.Current;
IComparable maxProjection = projectionToComparable(e.Current);
while (e.MoveNext()) {
IComparable currentProjection = projectionToComparable(e.Current);
if (currentProjection.CompareTo(maxProjection) > 0) {
max = e.Current;
maxProjection = currentProjection;
}
}
return max;
}
}
var groups = words.GroupBy(x => x);
var max = groups.Max(x => x.Count());
var top = groups.First(y => y.Count() == max).Key;
s.GroupBy(x => x).Aggregate((IGrouping<string,string>)null, (x, y) => (x != null && y != null && x.Count() >= y.Count()) || y == null ? x : y, x => x);
s.GroupBy(x => x).Select(x => new { Key = x.Key, Count = x.Count() }).Aggregate(new { Key = "", Count = 0 }, (x, y) => x.Count >= y.Count ? x : y, x => x);