区间交叉口

时间:2013-01-08 08:28:29

标签: java algorithm intersection intervals interval-intersection

我写了一个类来检查两个整数区间是否重叠。 但是我不太喜欢这个解决方案。我认为有可能以更好,更简单的方式做到这一点。

public class IntegerInterval implements Interval {
private Integer start;
private Integer end;

public IntegerInterval(Integer start, Integer end) {
    this.start = start;
    this.end = end;
}

public Integer getStart() {
    return start;
}

public Integer getEnd() {
    return end;
}

public boolean isOverlapping(IntegerInterval other) {
    if (other != null) {
        return isInInterval(start, other) || isInInterval(end, other)
                || isInInterval(other.start, this) || isInInterval(other.end, this);
    }
    return false;
}

public boolean isInInterval(Integer number, IntegerInterval interval) {
    if (number != null && interval != null) {
        if(interval.getStart() == null && interval.getEnd() != null) {
            return number.intValue() <= interval.getEnd().intValue();
        }
        if(interval.getStart() != null && interval.getEnd() == null) {
            return number.intValue() >= interval.getStart().intValue();
        }
        if(interval.getStart() == null && interval.getEnd() == null) {
            return true;
        }
        return interval.getStart() <= number && number <= interval.getEnd();
    }
    else if(number == null && interval != null) {
        return interval.getStart() == null && interval.getEnd() == null;
    }
    return false;
}

}

3 个答案:

答案 0 :(得分:2)

您应该将startend包装在能够封装Comparable的特定null类中。这样,您只需在compareTo中调用isInInterval,而无需为null打扰。

该课程也可明确代表正面和负面无限。

编辑:
如果向类声明添加类型参数<T extends Comparable<T>>并将startend类型声明为Comparable<T>,则可以使用任何实现{{1}的类型与Comparable {而不仅仅是Interval

答案 1 :(得分:2)

以下代码应该更简单:

public boolean isOverlapping(IntegerInterval other) {
    if (other == null) return false; // for readability's sake, this condition is pulled out

    // overlap happens ONLY when this's end is on the right of other's start
    // AND this's start is on the left of other's end.
    return (((this.end == null) || (other.start == null) || (this.end.intValue() >= other.start.intValue())) &&
        ((this.start == null) || (other.end == null) || (this.start.intValue() <= other.end.intValue())));
}

更新如果Date按实际要求的@Adam进行比较,则代码为:

private static boolean dateRangesAreOverlaping(Date start1, Date end1,
                                               Date start2, Date end2) {
return (((end1 == null) || (start2 == null) || end1.after(start2)) &&
         ((start1 == null) || (end2 == null) || start1.before(end2)));

}

答案 2 :(得分:1)

假设start < endstart相对于other的位置应该有3个检查:左,中,右(右边是完整性,因为没有交叉点)。所以这里有两个剩余的支票:

 (start <= other.start && end >= other.start) || 
 (start >= other.start && start <= other.end)  
 // start > other.end means no intersection as end > start > other.end

如果您检查start的位置为if,那么第二次检查可能只是(start <= other.end)

 if (start <= other.start) return end >= other.start;
 else if (start <= other.end) return true;
 else return false;

根据您的需要调整“=”部分,并适当地添加null个检查(例如,使用SpaceTrucker的答案来使comaprison与null隐藏在类中)。