-2

次のようなリストがあります(簡潔なソリューションを提供するコレクションのタイプとして実装できます):

4,1,5,2,1,3,8,1,6,4,2,3

リストは実際には 3 つの値のグループであり、その長さは常に 3 の倍数になります。グループの最初の 2 つの値とグループの 3 番目の値の間に関係はありません。

3つおきの値がそのまま残るように配列をソートしたいと思います。私が与えた例では、結果は次のようになります。

1,1,5,1,2,3,2,4,6,4,8,3

インデックス 0、1、3、4、6、および 7 を持つ要素が並べ替えられました。インデックス 2、5、および 8 の要素はソートされていません。

これを表現する別の方法は、リストが x,x,y,x,x,y,x,x,y,x,x,y であり、x のみを並べ替えたいと想像することです。

私はアルゴリズムを書くことができますが、これを行う簡潔な方法があるのだろうか?

4

3 に答える 3

2

これを本当に効率的に行うことに必死でない限り、私は簡単な解決策を選びます。

  • 並べ替えたい要素を新しいリストに抽出します
  • リストを並べ替える
  • 並べ替えたい要素を固定要素とマージして新しいリストを作成するか、(可変コレクションを使用したい場合) 並べ替えた要素を元のリストに戻します。

次のようなものです:

var list = ...; // Get hold of the whole list.
var sortedElements = list.Where((value, index) => index % 3 != 2)
                         .OrderBy(x => x)
                         .ToList();
for (int i = 0; i < sortedElements.Count; i++)
{
    int index = (i / 2) * 3 + i % 2;
    list[index] = sortedElements[i];
}
于 2012-12-28T11:05:59.270 に答える
1

次のlinqを試してください

var ints = new int[]{4,1,5,2,1,3,8,1,6,4,2,3};
var result = ints.Where((i,j) => j%3!= 2).OrderBy(i=>i).ToArray();

var index = ints.Select ((i , j)=> 
    {
        if (j%3==2) 
            return i; 
        else 
            return result[(j/3)*2 + j%3];
    });

仕組み
1. 不要な値を無視してソートされた配列を取得します
。 2. ソートされた配列の各トリプレットの最初の 2 つの値を使用して、元の配列から出力配列を準備します。

于 2012-12-28T11:08:26.463 に答える
0

3 つおきの値を取り出して個別に保持し、すべてを並べ替えて値を再度挿入するのが最も簡単だと思います。

numbers.Where((n, index) => (index + 1) % 3 == 0);
numbers.Where((n, index) => (index + 1) % 3 != 0);

これにより、3 番目のインデックスと並べ替える必要のあるもののリストが得られます。

于 2012-12-28T11:06:03.823 に答える