2009-04-21 49 views
3

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

哦,并且整数存储在字符串中,例如“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; 
      } 
     } 
    } 
} 

但据我所知,这是泡沫排序,正确吗? 我应该实施什么呢?快速排序?另外,我可能需要编写它的帮助。

哦,我的列表中包含短存储在字符串

而且号码2000元,我打电话给我的IComparer是这样的:

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

回答

6

假设你想存储为一个字符串的整数的值进行排序,你可以简单地做这样的事情:

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

D'oh - 几乎相同,但你打我3分钟。 +1 ;-p – 2009-04-21 09:39:26

4

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

+0

哦?但是,如果我只是打电话列表。排序()我的列表没有得到排序整数的整数大小 - 我想要存档 – CasperT 2009-04-21 09:29:47

+0

啊,我想我现在理解一点。所以这个比较器在我的List.Sort中被调用意味着我正在做快速排序,对吗?而不是bubblesort,我原本以为我是如何写我的比较器 – CasperT 2009-04-21 16:29:50

1

因此,您有一个表示int的字符串列表作为输入,并且您想要一个ints的排序列表作为输出吗?

你似乎在这里做了很多工作,得到你想要的结果 - 你可以利用一些LINQ到让你的结果是这样的:

使用系统;

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千余种手动优化排序算法 - 这是不是真的这么多项目进行排序,除非那是“所有”您的应用程序在做什么。

+0

这似乎是这样一个浪费,生成/创建一个全新的列表:) 那么,它只是我的代码的一部分,但我想我应该研究这个问题,并在这个问题上变得更好 - 这是一个好主意,以获得排序的挂钩。虽然我喜欢你的LINQ解决方案,但我会进一步了解它 – CasperT 2009-04-21 09:37:05

+0

是的,这是一个好主意,得到排序的处理,毫无疑问:) – 2009-04-21 09:47:22

1

没有,用于排序列表中的算法是快速排序,这样你就可以这不会轻易改善。

List<T>.Sort method

该方法使用Array.Sort,其 使用快速排序算法。

我完成了比较器:

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; 
       } 
      } 
     } 
    } 

} 

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

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(); 
1

我想你应该首先将string秒值进行转换来的int临时列表如下(迄今为止)的其他代码遍地转换串一遍,每次比较。 (如果保持null的重要性,你也可以使用可为空的整数)。之后,您对列表进行排序,并在必要时转换回字符串。