-1

我正在开发一个程序,该程序利用重载到我创建的结构的 List 对象。

随着时间的推移,这个程序不断地增加列表的大小。我正在寻找一种算法,它将在 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 是我的第二个帮助操作的列表。

4

1 回答 1

2

List (框架中的任何IList )*的默认实现保持具有连续索引的项目。也就是说,一旦你删除了一个项目,列表中在它之后的所有项目都会向后移动一个位置。需要明确的是,如果您有:

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

如果您删除BthenC并将D向后移动一个空格:

 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 回答