Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有属性的可能相交范围列表的清理算法_C#_List_Range - Fatal编程技术网

C# 具有属性的可能相交范围列表的清理算法

C# 具有属性的可能相交范围列表的清理算法,c#,list,range,C#,List,Range,我有这些对象的范围和属性列表。我的目标是获取这些对象的列表,并创建一个没有范围重叠的新列表。当两个范围重叠时,重叠区域可以替换为具有特性并集的对象。我希望图片能比文字更好地解释这一点 范围的解开 我能够用下面的代码实现这一点,但是它相当笨拙,并且使用了我试图避免的goto。此代码背后的方法是比较每对范围,如果存在交叉点,则将两个RangeObjects替换为最多三个RangeObjects: 一个用于与rangeObject2不相交的rangeObject1部分 一个用于与rangeObje

我有这些对象的范围和属性列表。我的目标是获取这些对象的列表,并创建一个没有范围重叠的新列表。当两个范围重叠时,重叠区域可以替换为具有特性并集的对象。我希望图片能比文字更好地解释这一点

范围的解开

我能够用下面的代码实现这一点,但是它相当笨拙,并且使用了我试图避免的goto。此代码背后的方法是比较每对范围,如果存在交叉点,则将两个RangeObjects替换为最多三个RangeObjects:

  • 一个用于与rangeObject2不相交的rangeObject1部分
  • 一个用于与rangeObject1不相交的rangeObject2部分
  • 一个用于rangeObject1和rangeObject2与联合属性的交集
类范围对象
{
RangeObject(int开始、int结束、列表属性)
{
开始=开始;
结束=结束;
属性=属性;
}
public int Start{get;set;}
公共int End{get;set;}
公共整数长度{get=>End-Start;}
公共列表属性{get;}
公共布尔值IsInRange(int值)
{
返回值>开始值和结束值rangeObject2.Start | |((rangeObject1.Start==rangeObject2.Start)&&(rangeObject1.Length>rangeObject2.Length)))
{
RangeObject temp=rangeObject1;
rangeObject1=rangeObject2;
rangeObject2=温度;
}
如果(rangeObject1.Start==rangeObject2.Start&&rangeObject1.End==rangeObject2.End)//范围相等
{
result.Add(新建RangeObject(rangeObject1.Start,rangeObject1.End,rangeObject1.Properties.Union(rangeObject2.Properties.ToList());//返回一个联合属性的RangeObject
}
else if(rangeObject1.IsInRange(rangeObject2.Start)&&rangeObject1.IsInRange(rangeObject2.End))//Range1中包含的Range2
{
if(rangeObject1.Start!=rangeObject2.Start)
{
添加(新的RangeObject(rangeObject1.Start,rangeObject2.Start-rangeObject1.Start,rangeObject1.Properties));
}
添加(新的RangeObject(rangeObject2.Start,rangeObject2.Length,rangeObject1.Properties.Union(rangeObject2.Properties.ToList());
if(rangeObject1.End!=rangeObject2.End)
{
添加(新的RangeObject(rangeObject2.End,rangeObject1.End-rangeObject2.End,rangeObject1.Properties));
}
}
else if(rangeObject1.IsInRange(rangeObject2.Start))//Range1中包含的Range2.Start
{
添加(新的RangeObject(rangeObject1.Start,rangeObject2.Start-rangeObject1.Start,rangeObject1.Properties));
添加(新的RangeObject(rangeObject2.Start,rangeObject1.End-rangeObject2.Start,rangeObject1.Properties.Union(rangeObject2.Properties.ToList());
添加(新的RangeObject(rangeObject1.End,rangeObject2.End-rangeObject1.End,rangeObject2.Properties));
}
否则//没有交叉口,不应该发生
{
结果。添加(rangeObject1);
结果。添加(rangeObject2);
}
返回结果;
}
}

关于如何更优雅地实现这一点,有什么想法吗?或者至少避免开始,因为当我切割范围时,我最终会将它们重新定位到末尾,并更改列表的长度/顺序,因此很难判断我比较了哪些范围。

以下是一种摆脱“转到”的方法:

私有列表解开范围列表(列表列表)
{
列表1=新列表(列表);
list1.Sort();
int start=0;
而(!CheckSomething(list1,ref start));
list1.Sort();
返回列表1;
}
私有bool CheckSomething(列表列表1,ref int start)
{
for(int i=start;i
为了简单起见,我首先得到一个足够大的范围,以包括所有其他范围,但带有一个空的
Properties
字段。这是通过获取所有范围的最小值和最大值来实现的

然后,我将一个接一个的范围与所谓的untangl结合起来