Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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#_.net_List_Range_Intersect - Fatal编程技术网

C# 重叠范围检查是否存在重叠

C# 重叠范围检查是否存在重叠,c#,.net,list,range,intersect,C#,.net,List,Range,Intersect,我有一个范围列表,我想知道它们是否重叠 我有以下代码。这似乎不起作用。有没有更简单的方法或有效的方法:) 提前谢谢你的建议 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private IList<Range> rangeList; private void Form1_Load(object sender,

我有一个范围列表,我想知道它们是否重叠

我有以下代码。这似乎不起作用。有没有更简单的方法或有效的方法:)

提前谢谢你的建议

   public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private IList<Range> rangeList;

    private void Form1_Load(object sender, EventArgs e)
    {
        rangeList.Add(new Range{FromNumber = 0, ToNumber = 100});
        rangeList.Add(new Range { FromNumber = 101, ToNumber = 200 });

        // this range should over lap and throw an exception 
        rangeList.Add(new Range { FromNumber = 199, ToNumber = 300 });

    }

    private bool RangesOverlap()
    {
        var bigList = new List<List<int>>();

        foreach (var range in this.rangeList)
        {
            bigList.Add(new List<int> { range.FromNumber , range.ToNumber });
        }

        IEnumerable<IEnumerable<int>> lists = bigList;

        return lists
         .Where(c => c != null && c.Any())
         .Aggregate(Enumerable.Intersect)
         .ToList().Count > 0;
    }
}


public class Range
{
    public int FromNumber { get; set; }
    public int ToNumber { get; set; }
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}
私有IList范围列表;
私有void Form1\u加载(对象发送方、事件参数e)
{
添加(新范围{FromNumber=0,TonNumber=100});
添加(新范围{FromNumber=101,tonNumber=200});
//该范围应超过圈数并引发异常
添加(新范围{FromNumber=199,TonNumber=300});
}
私人布尔·兰格索韦拉普()
{
var bigList=新列表();
foreach(此.rangeList中的变量范围)
{
添加(新列表{range.FromNumber,range.tonNumber});
}
IEnumerable list=bigList;
退货清单
.Where(c=>c!=null&&c.Any())
.聚合(可枚举.相交)
.ToList().Count>0;
}
}
公共类范围
{
public int FromNumber{get;set;}
public int ToNumber{get;set;}
}

首先合并编号,然后检查生成的列表是否按顺序排序:

rangeList
.OrderBy(p => p.FromNumber)
.Select(p => new[] { p.FromNumber, p.ToNumber })
.SelectMany(p => p)
.Aggregate((p, q) => q >= p ? q : int.MaxValue) == int.MaxValue

您只需稍微修改Rezaarab回答即可满足您的新要求:

rangeList
.Select(p => new[] { p.FromNumber, p.ToNumber })
.SelectMany(p => p.Distinct())
.Aggregate((p, q) => q >= p ? q : int.MaxValue) == int.MaxValue

这个问题的解决方案非常简单,只需编写自己的
RangeList:IList
,当指定的范围与集合中已有的一个或多个范围重叠时,其
Add()
方法会引发异常

工作示例:

class Range
{
    public int FromNumber { get; set; }
    public int ToNumber { get; set; }

    public bool Intersects(Range range)
    {
        if ( this.FromNumber <= range.ToNumber )
        {
            return (this.ToNumber >= range.FromNumber);
        }
        else if ( this.ToNumber >= range.FromNumber )
        {
            return (this.FromNumber <= range.ToNumber);
        }

        return false;
    }
}

class RangeList : IList<Range>
{
    private readonly IList<Range> innerList;

    #region Constructors

    public RangeList()
    {
        this.innerList = new List<Range>();
    }

    public RangeList(int capacity)
    {
        this.innerList = new List<Range>(capacity);
    }

    public RangeList(IEnumerable<Range> collection)
    {
        if ( collection == null )
            throw new ArgumentNullException("collection");

        var overlap = from left in collection
                      from right in collection.SkipWhile(right => left != right)
                      where left != right
                      select left.Intersects(right);

        if ( overlap.SkipWhile(value => value == false).Any() )
            throw new ArgumentOutOfRangeException("collection", "The specified collection contains overlapping ranges.");

        this.innerList = new List<Range>(collection);
    }

    #endregion

    private bool IsUniqueRange(Range range)
    {
        if ( range == null )
            throw new ArgumentNullException("range");

        return !(this.innerList.Any(range.Intersects));
    }

    private Range EnsureUniqueRange(Range range)
    {
        if ( !IsUniqueRange(range) )
        {
            throw new ArgumentOutOfRangeException("range", "The specified range overlaps with one or more other ranges in this collection.");
        }

        return range;
    }

    public Range this[int index]
    {
        get
        {
            return this.innerList[index];
        }
        set
        {
            this.innerList[index] = EnsureUniqueRange(value);
        }
    }

    public void Insert(int index, Range item)
    {
        this.innerList.Insert(index, EnsureUniqueRange(item));
    }

    public void Add(Range item)
    {
        this.innerList.Add(EnsureUniqueRange(item));
    }

    #region Remaining implementation details

    public int IndexOf(Range item)
    {
        return this.innerList.IndexOf(item);
    }

    public void RemoveAt(int index)
    {
        this.innerList.RemoveAt(index);
    }

    public void Clear()
    {
        this.innerList.Clear();
    }

    public bool Contains(Range item)
    {
        return this.innerList.Contains(item);
    }

    public void CopyTo(Range[] array, int arrayIndex)
    {
        this.innerList.CopyTo(array, arrayIndex);
    }

    public int Count
    {
        get { return this.innerList.Count; }
    }

    public bool IsReadOnly
    {
        get { return this.innerList.IsReadOnly; }
    }

    public bool Remove(Range item)
    {
        return this.innerList.Remove(item);
    }

    public IEnumerator<Range> GetEnumerator()
    {
        return this.innerList.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.innerList.GetEnumerator();
    }

    #endregion
}
类范围
{
public int FromNumber{get;set;}
public int ToNumber{get;set;}
公共布尔交叉点(范围)
{
if(this.FromNumber=range.FromNumber);
}
else if(this.tonNumber>=range.FromNumber)
{
返回(this.FromNumber left!=right)
在哪里左边!=右边
选择左。相交(右);
if(overlap.SkipWhile(value=>value==false).Any())
抛出新ArgumentOutOfRangeException(“集合”,“指定的集合包含重叠范围”);
this.innerList=新列表(集合);
}
#端区
私人布尔伊斯耐克兰格(射程)
{
如果(范围==null)
抛出新的ArgumentNullException(“范围”);
return!(this.innerList.Any(range.Intersects));
}
专用范围EnsureUniqueRange(范围)
{
如果(!IsUniqueRange(范围))
{
抛出新ArgumentOutOfRangeException(“范围”,“指定的范围与此集合中的一个或多个其他范围重叠”);
}
返回范围;
}
公共范围此[int索引]
{
得到
{
返回此.innerList[索引];
}
设置
{
this.innerList[index]=EnsureUniqueRange(值);
}
}
公共空白插入(整数索引,范围项)
{
this.innerList.Insert(index,EnsureUniqueRange(item));
}
公共无效添加(范围项目)
{
this.innerList.Add(EnsureUniqueRange(item));
}
#区域剩余实施细节
public int IndexOf(范围项)
{
返回此.innerList.IndexOf(项);
}
公共无效删除(整数索引)
{
this.innerList.RemoveAt(索引);
}
公共空间清除()
{
this.innerList.Clear();
}
公共布尔包含(范围项)
{
返回此.innerList.Contains(项);
}
public void CopyTo(范围[]数组,整数数组索引)
{
this.innerList.CopyTo(数组,arrayIndex);
}
公共整数计数
{
获取{返回this.innerList.Count;}
}
公共图书馆是只读的
{
获取{返回this.innerList.IsReadOnly;}
}
公共布尔删除(范围项目)
{
返回此.innerList.Remove(项);
}
公共IEnumerator GetEnumerator()
{
返回此.innerList.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回此.innerList.GetEnumerator();
}
#端区
}
用法:

IList<Range> rangeList = new RangeList();

try
{
    rangeList.Add(new Range { FromNumber = 12, ToNumber = 12 });
    rangeList.Add(new Range { FromNumber = 13, ToNumber = 20 }); // should NOT overlap
    rangeList.Add(new Range { FromNumber = 12, ToNumber = 20 }); // should overlap
}
catch ( ArgumentOutOfRangeException exception )
{
    Console.WriteLine(exception.Message);
}
IList rangeList=new rangeList();
尝试
{
添加(新范围{FromNumber=12,TonNumber=12});
rangeList.Add(新范围{FromNumber=13,TonNumber=20});//不应重叠
rangeList.Add(新范围{FromNumber=12,TonNumber=20});//应该重叠
}
捕获(ArgumentOutOfRangeException异常)
{
Console.WriteLine(异常消息);
}

过去,我面临一个挑战,我必须为用户创建的范围(整数或实数)编写验证算法。我必须检查三件事:

  • 范围是连续的
  • 范围不重叠

  • 如果单个范围的“到”和“从”可以相等,但在多个范围上不能重叠,则“低”值必须始终为。我们需要如何改变这一点?添加(新范围{FromNumber=12,TonNumber=12});添加(新范围{FromNumber=13,TonNumber=20})@吉佩斯:我认为这对雷扎阿拉伯有点不公平,因为他给了你一个极好的答案。现在您添加了一个额外的问题,这可能意味着RezaArab失去了他接受的答案。这里只需注意:此解决方案是在假定
    范围列表
    范围.FromNumber
    成员的升序排序的情况下工作的。如果不正确,只需使用
    rangeList.OrderBy(p=>p.FromNumber)。选择(…
    感觉这应该是一个新问题,而不是对现有问题的悬赏。堆栈溢出对于随着时间的推移而演变的问题不太有效-这对回答最初问题的人不公平,因为后面的任何人都会认为他们没有抓住重点。(另外,我不知道其他人,但我不知道)
     //Let's hardcode an array of integers (it can be of reals as well):
     $range = array
     (
         array(1, 13),
         array(14, 20),
         array(21, 45),
         array(46, 50),
         array(51, 60)
     );
    
     //And the validation algorithm:
     $j = 0;
     $rows = sizeof($range);
     $step = 1;   // This indicates the step of the values.
                  // 1 for integers, 0.1 or 0.01 for reals
    
     for ($x=0; $x<$rows; $x++)
         for ($y=0; $y<$rows; $y++) {
             if ( ($range[$x][0] <= $range[$y][0]) AND ($range[$y][0] <= $range[$x][1]) AND ($x != $y) ) {
                 echo "Ranges intercepting";   // replace with error handling code
                 break 3;
             }
             if ( $range[$x][0] > $range[$x][1] ) {
                 echo "Not valid high & low";  // replace with error handling code
                 break 3;
             }
             if ( $range[$x][0] - $range[$y][1] == $step ) {
                 $j++;
             }
         }
     if ( $j != $rows - $step )
         echo "Not continuous";    // replace with error handling code