2009-04-21 4 views
3

私は整数の損失を格納するリストを持っています。 リストを実際のintのサイズで並べ替えるため、デフォルトのList.Sort()がうまくいきません。 これまでのところ、私はこれを持っています:リストを最適化する<T>。ソート(Comparer)

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

私の知る限り、これはバブルソートです。 代わりに何を実装する必要がありますか?クイックソート?また、私はそれを書くのを助ける必要があるかもしれません。

ああ、私のリストは、文字列も

に数字を格納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 –

+0

まあ、初めてのことです:) –

+0

これは、自分のIComparerをList.Sort()に追加するよりも速い/遅い/同じ場合には何か手掛かりはありますか? Linqがこのような状況でどのくらいの速さを持つことができるか分かりません:) – CasperT

4

あなたは比較演算とソートアルゴリズムことに注意する必要があります互いに決定しないでください。したがって、この比較関数は、バブルソート、クイックソート、ヒープソート、または他のソートアルゴリズムで使用できます。 List.SortのビルトインソートアルゴリズムはMSDNによればquicksortです。

+0

ああ?しかし、リスト.Sort()を呼び出すと、intのサイズの後にリストがソートされません。アーカイブしたいところです。 – CasperT

+0

ああ、もう少し理解していると思います。だから、この比較人が私のリストで呼び出されています。ソートは私がクイックソートをやっていることを意味します、正しい?と私は元の私の比較人を書いていた方法のために考えていた気泡はありません – CasperT

1

入力としてintを表す文字列のリストがあり、出力としてintのソートされたリストが必要ですか?

あなたが望む結果を得るために、ここで多くの作業をやっているように見える - あなたは、このような検索結果を得るためにいくつかの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); 
     } 
    } 
} 

そして、私は2000個のアイテムを手動でソートアルゴリズムの最適化を心配することはないだろう - それはそれはでない限り「すべて」のアプリケーションがやっているソートするために本当に多くの項目ではありません。

+0

それは完全に新しいリストを生成/作成するような浪費のようです:) ナー、それは私のコードの一部ですが、私は問題を調べてより良くなるようにする必要があります。ソートの問題を解決することをお勧めします。私はあなたのLINQソリューションが好きです。少しだけ詳しく見ていきます。 – CasperT

+0

はい、ソートについては疑問の余地はありません:) –

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

ネガやゼロ詰めの値がないことを望みます。 –

+0

それが速いかどうか分かりますか? :)私はそれが好きです! +1 – CasperT

+0

ParseInt32メソッドがInt32.Parseより速い場合は、はい、それは約10倍速いです。 – Guffa

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

は、私はあなたが最初にそれぞれの比較のために、何度も何度も文字列を変換する(これまでに)、ここで他のコードとしてintの一時リストにstring秒に変換するべきだと思います。 (nullの周りが重要である場合は、null可能なintを使用することもできます)。その後、リストをソートし、必要に応じて文字列に変換し直します。

+0

文字列の解析が最大のパフォーマンスのホッグとして飛び出すので、+1 –

関連する問題