我有一个未分类的List<WordCount>
class WordCount
{
string word;
int count;
}
现在我必须按照计数的降序显示前20项。我怎么能有效地编码呢?目前我将设置一个最小整数-1(所有count
> = 1)并在内部使用foreach循环执行20次迭代的for循环。这是一个问题,因为List
中的最后几个元素可能有count
为1,而前几个元素可能有count
1的元素所以现在我被困在伪代码上这个实现按顺序显示它们。
我不能使用LINQ或List
类的方法以外的任何其他东西。我个人认为我必须以某种方式使用Sort()
和CompareTo()
完成此专长。这是一个大脑扭转,这就是为什么必须使用给定的限制来完成它。
答案 0 :(得分:1)
这应该有效:
List<WordCount> counts = new List<WordCount>();
//Fill the list
var result = counts.OrderBy(c => c.Count).Take(20);
降序:
var result = counts.OrderByDescending(c => c.Count).Take(20);
这是一个没有任何.NET方法的解决方案。首先使用算法对列表进行排序,在这种情况下,我使用了Bubblesort(对较大的集合没有效果)。然后我从排序结果中取出20个第一个元素:
public class WordCount
{
public string Word { get; set; }
public int CharCount { get; set; }
}
public List<WordCount> SortList(List<WordCount> list)
{
WordCount temp;
for (int i = list.Count -1; i >= 1; i--)
{
for (int j = 0; j < list.Count -1; j++)
{
if(list[j].CharCount < list[j+1].CharCount)
{
temp = list[j];
list[j] = list[j+1];
list[j+1] = temp;
}
}
}
return list;
}
public List<WordCount> TakeNItems(int n, List<WordCount> list)
{
List<WordCount> temp = new List<WordCount>();
for(int i = 0; i < n; i++)
temp.Add(list[i]);
return temp;
}
//Usage:
var result = SortList(counts);
result = TakeNItems(20, result);
是的,也可以使用Sort()
和CompareTo()
。这需要对您的课程进行一些更改,因为当您尝试现在使用Sort()时,您将获得InvalidOperationException
。这是因为WordCount类没有实现IComparable
接口。实现接口意味着您必须覆盖Equals()
和GetHashCode()
方法并提供自己的比较器。这是一个基于List(T).Sort Method的简单实现:
public class WordCount : IComparable<WordCount>
{
public string Word { get; set; }
public int CharCount { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
WordCount wc = obj as WordCount;
return wc == null ? false : Equals(wc);
}
public int CompareTo(WordCount wc)
{
//Descending
return wc == null ? 1 : wc.CharCount.CompareTo(CharCount);
//Ascending
//return wc == null ? 1 : CharCount.CompareTo(wc.CharCount);
}
public override int GetHashCode()
{
return CharCount;
}
public bool Equals(WordCount wc)
{
return wc == null ? false : CharCount.Equals(wc.CharCount);
}
}
//Usage:
List<WordCount> counts = new List<WordCount>();
//Fill the list
counts.Sort();
对于20个项目的限制,您可以编写自己的扩展方法,它基本上与 Enumerable.Take Method 相同:
public static class Extensions
{
public static IEnumerable<T> TakeN<T>(this List<T> list, int n)
{
for(int i = 0; i < n; i++)
yield return list[i];
}
}
//Usage:
List<WordCount> counts = new List<WordCount>();
//Fill the list with 10000 items and call TakeN()
IEnumerable<WordCount> smallList = counts.TakeN(20);
//Or
counts = counts.TakeN(20).ToList();
希望这能澄清一切! ;)
答案 1 :(得分:0)
最直接的解决方案,使用System.Linq:
var words = new List<WordCount>();
var result = from w in words orderby w.count descending select w.word;
result = result.Take(20);
这是最方便,最明确的解决方案,因此在可能的情况下使用Linq。结果也是IEnumerable<WordCount>
,因此编译器可以进行优化,例如延迟枚举,在询问之前不会计算所有元素。