-1

我有一个这样的 POCO:

class Poco{
    int first;
    int last;
    int category;
}

和一份清单

List<Poco> pocoList;

我需要从列表中删除与指定类别的项目重叠的项目,重叠定义为:

if (a.category!=category && (a.first >= b.first && a.first <= b.last) || (a.last >= b.first && a.last <= b.last)){
  // delete item a 
}

两个重叠的项目永远不会有相同的类别。最后总是大于第一个。第一个和最后一个定义一个范围。可能存在不止一个重叠。

对列表进行排序,使得 List[n].start < List[n+1].start 始终为真。

例如,给定类别 10,我需要删除所有不属于类别 10 的项目,并且该项目范围的任何部分与类别 10 的项目范围重叠。

我当前的实现是粗略的,在分析我的应用程序时,我可以看到使用它的处理分支的整个时间的 65% 以上都花在了这个循环中,这不足为奇。

for (int i=object.pojoList.Count-1;i>=0;i--){
    for (int j=object.pocoList.Count-1;j>=0;j--){
        if (pocoList[i].overlaps(pocoList[j],category){
            pocoList.RemoveAt(j);
        }            
    }
}

我觉得必须有一种方法可以使用比较器或 LINQ 删除项目,但我无法弄清楚。

有什么建议么?谢谢你。

4

2 回答 2

1

由于您的输入列表是start有序的,您可以尝试类似

List<Poco> potentialOverlaps = new List<Poco>();
for (int i = 0; i < pocoList.Count; i++)
{
    var currentPoco = pocoList[i];

    // Clear out overlaps that end before this poco starts.
    potentialOverlaps.RemoveAll(p => p.last < currentPoco.first);

    if (currentPoco.category == category)
    {
        potentialOverlaps.Add(currentPoco);
    }
    else if (potentialOverlapsCount > 0)
    {
        pocoList.RemoveAt(i);
        i--;
    }
}

结果可能与您的代码给出的不同,但它应该与您描述的行为相匹配。

它跟踪Poco您选择的类别中“尚未结束”的;如果它遇到一个类别外Poco并且有任何“尚未结束”,它必须与其中一个重叠,以便可以删除。

于 2012-12-03T11:20:56.380 回答
0

你可以让你的类实现 IComparer。

您必须以返回 1、0 或 -1 的方式实现方法 Compare(Object, Object),分别表示更大、相等或更少。

一个好例子的来源:链接

您可以在一个列表中设置另一个列表的分隔符。然后,在使用上述方法进行排序时,如果该值与分隔符的范围重叠,则将其删除。

于 2012-12-03T10:49:32.240 回答