-1

作成した構造体にオーバーロードされた List オブジェクトを利用するプログラムに取り組んでいます。

このプログラムは、時間の経過とともにリストのサイズを無期限に増やし続けています。リストのサイズが 50 のときにトリガーされ、最初の 25 要素を削除し、後半の 25 を前半に移動し、26 番目の要素スポットで要素の追加を開始するアルゴリズムを探しています。

エントリと testEntries が上で定義され、作成した構造体にテンプレート化されていると仮定します。

if(entries.Count >= 50)
{
    testEntries = entries;
    int x = 0;
    for (x = 0; x < (entries.Count / 2); x++)
    {
        testEntries.RemoveAt(x);
    }
    for (x = 0; x < (entries.Count); x++)
    {
        testEntries.Add(entries[entries.Count / 2]);
    }
entries = testEntries;
}

//entries は私の元のリストです。testEntries は、操作に役立つ 2 番目のリストです。

4

1 に答える 1

2

List(フレームワーク内の任意のIList)*のデフォルトの実装は、連続したインデックスを持つアイテムを保持します。つまり、アイテムを削除すると、リストの後ろにあるすべてのアイテムが1つ前に移動します。明確にするために、あなたが持っている場合:

 0 -> A
 1 -> B
 2 -> C
 3 -> D

B次に削除するCと、D1スペース戻ります。

 0 -> A
 1 -> C
 2 -> D

*:Listのカスタム実装を使用していますか?


カスタムリストを使用しないと仮定します

それを知って、そしてあなたはリストの最初で削除しているので、あなたは最初の位置で必要な量のアイテムを削除することができます:

if(entries.Count >= 50)
{
    testEntries = entries;
    int x = 0;
    for (x = 0; x < (entries.Count / 2); x++)
    {
        testEntries.RemoveAt(0); // <--- Always removing the first item
    }
    //No need
    /*for (x = 0; x < (entries.Count); x++)
    {
        testEntries.Add(entries[entries.Count / 2]);
    }*/
    entries = testEntries;
}

また、前半、最初の25アイテム、または残り25アイテムだけを削除するかどうかを検討することもできます。上記のコードは前半を削除します。

最初の25を削除するには、で変更for (x = 0; x < (entries.Count / 2); x++)for (x = 0; x < 25; x++)ます。25個のアイテムが残るまで削除するには、しばらくお勧めします。

if(entries.Count >= 50)
{
    testEntries = entries;
    while (entries.Count > 25)
    {
        testEntries.RemoveAt(0);
    }
    entries = testEntries;
}

カスタムリストを使用すると仮定します

連続したインデックスを保持しないカスタムリストがある場合...後半を前半にコピーすることから始めることができます。その後、後半を削除することができます。

if(entries.Count >= 50)
{
    testEntries = entries;
    int x = 0;
    int pivot = (entries.Count / 2);
    //Copy
    for (x = pivot; x < entries.Count; x++)
    {
        testEntries[x - pivot] = testEntries[x];
    }
    //Remove
    for (x = pivot; x < entries.Count; x++)
    {
        testEntries.RemoveAt(x);
    }
    entries = testEntries;
}

ファイナルノート

これらはどれもスレッドセーフではありません。複数のスレッドが同時にオブジェクトにアクセスしている場合、予期しない結果が生じる可能性があります。何らかの形式の同期の使用を検討する必要があります。ロックフリーのソリューションを作成することは可能だと思いますが、それはこの投稿の範囲を超えています。

于 2013-01-27T06:48:01.553 に答える