找到2个间隔之间交点的最佳算法

时间:2016-10-02 10:38:00

标签: c# .net algorithm

我在数据库中有一个名为Control的表:

表格结构:

  

Id |名称| MinValue(十进制)|的MaxValue(十进制)

我对该表有一些限制,其中一个限制是: 没有交叉点

示例:如果表格中包含如下值:

  

第1行:1 | Test1 | 1.3 | 2.5 // 有效
  第2行:2 | Test2 | 3.3 | 4.5 // 有效
  第3行:3 | Test3 | 5 | 6 // 有效

现在,如果我想添加新记录,则不得与任何其他行相交

实施例

  

第4行:4 | Test4 | 5.1 | 10 // 无效 ,因为5到6的插槽是保留的   第5行:5 | Test5 | 1.0 | 1.4 // 无效 ,因为从1.3到2.5的插槽是保留的

我正在使用此代码,并且它运行良好,但我想知道是否有更好的解决方案和更高效:

var allRows = db.Control.ToList();
var minValue = control.MinimumValue;
var maxValue = control.MaximumValue;
bool flag = true;
foreach(var row in allRows)
{
    for(var i = minValue; i <= maxValue && flag ; i = decimal.Add( i , (decimal) 0.01))
    {
        if(i >= row.MinimumValue && i <= row.MaximumValue)
        {
            flag = false;
            min = row.MinimumValue;
            max = row.MaximumValue;
            break;
        }
    }
}

if (flag)
{
    //add
}
else
{
    //intersection
}

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

我认为这是一个O(LogN)问题......

保留按其起始值排序的细分。
在任何s[i].end < s[i+1].start

的有效列表i

在插入新细分时,找到它的位置(开始的位置比新细分最接近(但更小))称之为i

if((seg[i-1].end < new.start) && (seg[i+1].start > new.end)) 
    //OK to insert
else
    // intersect

答案 1 :(得分:0)

我们假设这是您尝试添加的对象:

var control = new Control()
{
    Name = 'name',
    MinValue = 5,
    MaxValue = 6
};

您可以执行以下操作:

var biggerThanMinValue = db.Control.Count(x => x.MinValue >= control.MinValue) != 0;
var biggerThanMaxValue = db.Control.Count(x => x.MaxValue >= control.MaxValue) != 0;
if (!biggerThanMinValue && !biggerThanMinValue)
{
    db.Control.Add(control); // or whatever your add operation is
}

通过这样做你:

  • 不要将整个表加载到内存中 - &gt;性能增益时间,流量和内存
  • 让数据库使用它的数据结构/算法来验证是否可以添加项目(数据库应该能够优化此请求) - &gt;另一个性能提升(cpu +时间)
  • 有更清晰的后端代码
  • 需要更少的代码来测试

编辑:我想你也可以要求数据库按最小/最大值对表进行排序,然后进行一些验证(1或2 ifs),但第一种方法更好,imo。