任何人都可以为我简化这个算法吗?

时间:2010-04-20 01:19:06

标签: c# .net algorithm

基本上我只是想检查一个时间段是否与另一个时间段重叠。 空结束日期表示无穷大。任何人都可以为我缩短这个,因为它很难阅读。干杯

    public class TimePeriod
    {
        public DateTime StartDate { get; set; }
        public DateTime? EndDate { get; set; }

        public bool Overlaps(TimePeriod other)
        {
            // Means it overlaps
            if (other.StartDate == this.StartDate
                || other.EndDate == this.StartDate
                || other.StartDate == this.EndDate
                || other.EndDate == this.EndDate)
                return true;

            if(this.StartDate > other.StartDate)
            {
                // Negative
                if (this.EndDate.HasValue)
                {
                    if (this.EndDate.Value < other.StartDate)
                        return true;
                    if (other.EndDate.HasValue && this.EndDate.Value < other.EndDate.Value)
                        return true;
                }

                // Negative
                if (other.EndDate.HasValue)
                {
                    if (other.EndDate.Value > this.StartDate)
                        return true;
                    if (this.EndDate.HasValue && other.EndDate.Value > this.EndDate.Value)
                        return true;
                }
                else
                    return true;
            }
            else if(this.StartDate < other.StartDate)
            {
                // Negative
                if (this.EndDate.HasValue)
                {
                    if (this.EndDate.Value > other.StartDate)
                        return true;
                    if (other.EndDate.HasValue && this.EndDate.Value > other.EndDate.Value)
                        return true;
                }
                else
                    return true;

                // Negative
                if (other.EndDate.HasValue)
                {
                    if (other.EndDate.Value < this.StartDate)
                        return true;
                    if (this.EndDate.HasValue && other.EndDate.Value < this.EndDate.Value)
                        return true;
                }
            }

            return false;
        }
    }

4 个答案:

答案 0 :(得分:15)

public bool Overlaps(TimePeriod other)
{
    return (other.StartDate >= StartDate && 
               (EndDate == null || other.StartDate <= EndDate.Value)) ||
           (StartDate >= other.StartDate &&
               (other.EndDate == null || StartDate <= other.EndDate.Value))
}

答案 1 :(得分:11)

这个怎么样:

public bool Overlaps(TimePeriod other)
{
    bool isOtherEarlier = this.StartDate > other.StartDate;
    TimePeriod earlier = isOtherEarlier  ? other : this;
    TimePeriod later = isOtherEarlier ? this : other;
    return !earlier.EndDate.HasValue || earlier.EndDate > later.StartDate;
}

答案 2 :(得分:3)

检查出来:DateTimeOverlaps

一般来说,如果所有变量都是可以为空的日期时间,那么

   return (StartA.HasValue? StartA.Value:DateTime.Minimum) <= 
             (EndB.HasValue? EndB.Value:DateTime.Maximum)  && 
          (EndA.HasValue? EndA.Value:DateTime.Maximum) >= 
              (StartB.HasValue? StartB.Value:DateTime.Minimum);

这个概念(如链接中所述)非常简单, 简单地 简明 表达以上。

如果开始在其他人结束之前,而结束在另一个开始之后,则表示您有重叠。这说明了一切,所有必要的,在一个带有两个子句的简单句子中,无论你编写什么代码,都应简明扼要地映射到这个简单的概念而不会混淆它。添加额外的不必要的复杂性不会增加理解,它只会增加长度。

失败案例1:TopStart在其他结束后失败

       |----------|
|--|

失败案例2:其他开始后的TopEnd - 失败

   |-----------|
                   |------|

在所有其他情况下,start在其他结束之前,end在其他开始之后。

案例A

    |----------|  
|-----|

案例B

    | ---------|
|-------------------|

案例C

|-----------|
   |------|

案例D

   |-----------|
       |-------------|

答案 3 :(得分:2)

无论何时处理纯布尔逻辑,您都可以将算法提炼为单个语句。但不要以为只是因为你可以,你应该。除非性能至关重要,否则请始终在紧凑的代码上使用可读代码。 (不一定是紧凑性==表现,必然)

这很容易阅读,因为它完全由单个AND表达式组成,很明显它们都决定了非重叠:

public bool Overlaps(TimePeriod other)
{
    if (other.EndDate.HasValue && other.EndDate < StartDate)
        return false;

    if (EndDate.HasValue && EndDate < other.StartDate)
        return false;

    if (!EndDate.HasValue && other.EndDate < StartDate)
        return false;

    if (!other.EndDate.HasValue && EndDate < other.StartDate)
        return false;

    return true;
}

不是其他答案都不好(我喜欢Adam的;他的格式化显然是为了提高可读性)。我只是这样说,因为很明显你是一个初学者,我认为这是一个没有得到足够重视的教训(我很内疚)。有人(我认为Martin Fowler)曾经说过:“任何傻瓜都可以编写计算机理解的代码,但是一个优秀的程序员可以编写人类理解的代码。”