优化列表<t> .Sort(Comparer)</t>

时间:2009-04-21 09:22:29

标签: c# generics sorting collections

我有一个存储整数丢失的列表。 我不喜欢默认的List.Sort()工作,因为我希望列表按实际int的大小排序。 到目前为止,我有这个:

哦,并且整数存储在字符串中,例如“1234”。这是我无法改变的。

public class IntComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (x == null)
        {
            if (y == null)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }
            else
            {
                // If x is null and y is not null, y
                // is greater. 
                return -1;
            }
        }
        else
        {
            // If x is not null...
            //
            if (y == null)
            // ...and y is null, x is greater.
            {
                return 1;
            }
            else
            {
                // ...and y is not null, compare the 
                // lengths of the two strings.
                //
                int xInt = Convert.ToInt32(x);
                int yInt = Convert.ToInt32(y);

                if (x > y)
                {
                    // If the strings are not of equal length,
                    // the longer string is greater.
                    //
                    return 1;
                }
                else if (xInt == yInt)
                {
                    return 0;
                }
                else
                {
                    // If the strings are of equal length,
                    // sort them with ordinary string comparison.


        //
                return -1;
            }
        }
    }
}

但据我所知,这是冒泡的,对吗? 我该怎么办呢?快速排序?另外,我可能需要帮助写它。

哦,我的列表包含2千个元素,用于存储字符串中的数字

另外,我这样称呼我的IComparer:

IntComparer intSort = New IntComparer();
List<T>.Sort(intSort);

6 个答案:

答案 0 :(得分:6)

假设您想要按存储为字符串的整数值进行排序,您可以简单地执行以下操作:

numbers.Sort((x,y) => Int32.Parse(x).CompareTo(Int32.Parse(y)));

答案 1 :(得分:4)

您应该知道比较器和排序算法不会相互确定。所以这个比较器可以用于冒泡排序以及quicksort,heapsort或任何其他排序算法。根据MSDN,List.Sort的内置排序算法是快速排序。

答案 2 :(得分:1)

所以你有一个表示整数作为输入的字符串列表,你想要一个排序的整数列表作为输出?

你似乎在这里做了很多工作来获得你想要的结果 - 你可以利用一些Linq来得到你的结果:

使用System;

using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication6
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var unsortedListOfStringsAsInts = new List<string> {"1234", "2345", "7", "9"};
            var sortedListOfInts = unsortedListOfStringsAsInts.Select(x => int.Parse(x)).OrderBy(x => x).ToList();

            foreach (var i in sortedListOfInts)
                Console.WriteLine(i);
        }
    }
}

我不会担心使用2千个项目手动优化排序算法 - 除非你的应用程序正在进行“全部”操作,否则排序的项目并不是很多。

答案 3 :(得分:1)

不,用于排序列表的算法是QuickSort,因此您无法轻易改进。

List<T>.Sort method

  

此方法使用Array.Sort,其中   使用QuickSort算法。

我完成了比较器:

public class IntComparer : IComparer<string> {

    private static int ParseInt32(string text) {
        long value = 0;
        foreach (char c in text) {
                if (c >= '0' && c <= '9') {
                value = value * 10 + c - '0';
            } else {
                throw new FormatException();
            }
        }
        if (value > int.MaxValue) throw new OverflowException();
        return (int)value;
    }


    public int Compare(string x, string y) {
        if (x == null) {
            if (y == null) {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            } else {
                // If x is null and y is not null, y
                // is greater. 
                return -1;
            }
        } else {
            // If x is not null...
            //
            if (y == null) {
                // ...and y is null, x is greater.
                return 1;
            } else {
                // ...and y is not null, compare the 
                // lengths of the two strings.
                //
                if (x.Length != y.Length) {
                    // If the strings are not of equal length,
                    // the longer string is greater.
                    return x.Length - y.Length;
                } else {
                    // compare numerically
                    int xInt = ParseInt32(x);
                    int yInt = ParseInt32(y);
                    return xInt - yInt;
                }
            }
        }
    }

}

编辑:
我添加了一个更快的整数解析器。由于比较器不处理负值,因此解析器也不会处理负值,这允许进一步优化。

答案 4 :(得分:1)

我认为您应该首先将string转换为int的临时列表,因为此处的其他代码(到目前为止)为每次比较反复转换字符串。 (如果保持null周围很重要,你也可以使用可空的整数)。之后,您对列表进行排序,并在必要时转换回字符串。

答案 5 :(得分:0)

只要您使用.net 3.5项目(Linq)

,这是一个快速示例
using System.Linq;
using System.Collections.Generic;

List<string> unorderedList = List<string>();
list.Add("3");
list.Add("5");
list.Add("2");
list.Add("10");
list.Add("-6");
list.Add("7");

List<string> orderedList = list.OrderBy(x => int.Parse(x)).ToList();