0

データグリッド A の列を Z に並べ替えようとしています。以下のコードは、「A」の間に「c」で始まる列を取得する以外に機能します (たとえば、a、a、a、a、c、a、 a、b、b、b)、これはコードを初めて実行したときに発生します。次に columnNames.Reverse(); を使用すると (Z から A) から columnNames.Sort() (A から Z) を再実行すると、正しく並べ替えられます。これはなぜでしょうか?

 List<string> columnNames = new List<string>();
 foreach (DataGridViewColumn col in dataGridView1.Columns)
 columnNames.Add(col.HeaderText);
 columnNames.Sort();
 foreach (DataGridViewColumn col in dataGridView1.Columns)
     col.DisplayIndex = columnNames.IndexOf(col.HeaderText);

ありがとう

4

1 に答える 1

1

あなたの例 ("(a,a,a,a,c,a,a,b,b,b)") では、列名は一意ではありません。したがって、ソートされた名前のリストでは、「a」の (最初の) インデックスは 0、「b」の (最初の) インデックスは 5、「c」の (最初の) インデックスは 8 になります。

したがって、列をループすると、テキスト「a」を含む列にインデックス「0」を繰り返し設定することになります。これを 2 回目に行うと、その位置の最初の列が移動されてスペースが作られます。結果は並べ替えというよりもカードのシャッフルに似ており、最終的な順序は元の順序に依存します。これが、並べ替えが 2 回目に正常に機能する理由です。最初のパスで、2 回目の試行が成功するように要素を「十分近く」配置します。

代わりに、次のようなものはどうでしょうか。インデックスが一意に割り当てられ、より効率的になります。(IndexOf への各呼び出しは O(N) であるため、元のコードは O(N^2) です。これは、少なくとも、インデックスを設定しても列コレクションが再配置されないと仮定すると、O(N log N) です。 .)

List<DataGridViewColumn> columns = new List<DataGridViewColumn>(dataGridView1.Columns);
columns.Sort( delegate(DataGridViewColumn a, DataGridViewColumn b) {
               return String.Compare( a.HeaderText, b.HeaderText ); }
int n = 0;
foreach( DataGridViewColumn col in columns )
   col.DisplayIndex = n++;
于 2008-12-05T01:51:53.430 に答える