繁体   English   中英

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

[英]Can anyone simplify this Algorithm for me?

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

    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;
        }
    }
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))
}

这个怎么样:

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;
}

看看这个: 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.

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

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

这很容易阅读,因为它完全由单个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)曾经说过:“任何傻瓜都可以编写计算机理解的代码,但是一个优秀的程序员可以编写人类理解的代码。”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM