【问题标题】:How to find out Intersection of a time range with the given set of time ranges in C#?如何在 C# 中找出时间范围与给定时间范围集的交集?
【发布时间】:2014-03-07 23:31:00
【问题描述】:

我有一个 GridView,它包含三列名称、开始日期和结束日期。 时间范围按排序顺序排列。表示 GridView 默认按开始日期排序。 用户想要插入一个带有名称、开始日期和结束日期的新行。 如果新开始日期和新结束日期之间的时间跨度与其他行的任何其他(可能超过一行)时间跨度相交。这些行将被删除,并且此新记录将插入到 GridView 中。如果与任何时间跨度都没有交集,则只需将其添加到 GridView。

如果编写了以下代码来找出两个日期之间的交集(数据类型为日期时间)。

    public class DateTimeRange
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }

    public bool Intersects(DateTimeRange test)
    {
        if (this.Start > this.End || test.Start > test.End)
            return false;
            //throw new InvalidDateRangeException();

        if (this.Start == this.End || test.Start == test.End)
            return false; // No actual date range

        if (this.Start == test.Start || this.End == test.End)
            return true; // If any set is the same time, then by default there must be some overlap. 

        if (this.Start < test.Start)
        {
            if (this.End > test.Start && this.End < test.End)
                return true; // Condition 1

            if (this.End > test.End)
                return true; // Condition 3
        }
        else
        {
            if (test.End > this.Start && test.End < this.End)
                return true; // Condition 2

            if (test.End > this.End)
                return true; // Condition 4
        }

        return false;
    }
}

所以我打算逐行迭代 GridView,存储与新重新编码相交的行的索引。在迭代之后,我将删除这些索引的行并插入新的重新编码。 所以我怀疑有没有更好的方法可以更简单或更简单地做到这一点。

前提条件:所有时间范围最初都是互斥的,表示行之间没有交集。

【问题讨论】:

  • 您的问题是什么?如果您询问您的代码,我不确定它是否会起作用,我相信您可以用更少的 if-else 块编写相同的逻辑。使用嵌套的 if 块,使用 = 运算符,这应该有助于降低复杂性。另外,考虑对这种方法进行单元测试

标签: c# asp.net datetime gridview


【解决方案1】:

在这些情况下,两个集合 a 和 b 不相交:

---|<--A-->|----------------
-------------|<--B-->|------

a.End < b.Start

--------------|<--A-->|-----
---|<--B-->|----------------

a.Start > b.End

所以如果你把这两种情况结合起来,你会得到:

a.End < b.Start || a.Start > b.End

现在你可以否定它了:

!(a.End < b.Start || a.Start > b.End)

使用 De Morgan 进行优化,您可以获得:

a.End >= b.Start && a.Start <= b.End

最后一个条件告诉你他们notdon't intersect(双重否定)。 所以它们相交。

不包括边界条件。将&lt;/&gt; 替换为&lt;=/&gt;=,反之亦然。

【讨论】:

  • 另外,不允许构造非法的范围对象,确保只有一种创建方法,并在其中定义开始时间和结束时间,结束时间应该大于开始时间
  • 非常好的解释!一次显示逻辑和代码:)
  • 很好解释,如何有效地将这个逻辑应用于一组时间范围?
  • 如果您有从 r1 到 rn 的 n 个范围,那么您需要将每个范围与所有其他范围进行比较,因此您必须比较 (n^2)/2。可能有一个定理可以将该数字减少到 n*ln(n) 但除非您需要每秒进行 1000 次以上的比较,否则我不会浪费时间...
  • 在我看来,如果范围是按开始日期排序的,您可能可以在更短的时间内比较它们,近似为 n,因为有一个基于 cursors 的算法,但是小批量真的不需要……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 2016-04-14
相关资源
最近更新 更多