显示未排序列表的前20个项目

时间:2013-11-21 11:23:38

标签: c# list

我有一个未分类的List<WordCount>

class WordCount
{
string word;
int count;
}

现在我必须按照计数的降序显示前20项。我怎么能有效地编码呢?目前我将设置一个最小整数-1(所有count> = 1)并在内部使用foreach循环执行20次迭代的for循环。这是一个问题,因为List中的最后几个元素可能有count为1,而前几个元素可能有count 1的元素所以现在我被困在伪代码上这个实现按顺序显示它们。

我不能使用LINQ或List类的方法以外的任何其他东西。我个人认为我必须以某种方式使用Sort()CompareTo()完成此专长。这是一个大脑扭转,这就是为什么必须使用给定的限制来完成它。

2 个答案:

答案 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);

[Edit2]使用Sort()/ CompareTo()

是的,也可以使用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>,因此编译器可以进行优化,例如延迟枚举,在询问之前不会计算所有元素。