简体   繁体   中英

C++ sort intervals struct as well as removing overlapping intervals

Here intervals is the same as Line. Although I figured out the correct solution for the two purposes:

1) sort intervals;

2) reject when adding intervals overlapping with existing ones.

struct Line {
    int down;
    int up;

    Line(int down, int up) {
        this->down = down;
        this->up = up;
    }
};

int main() {
    auto cmp = [] (const Line& a, const Line& b) {//NOTE: this can even detect the intersection, as well as sort the interval!!
        if (a.up <= b.down) return true;
        else return false;
    };

    set<Line, decltype(cmp)> s(cmp);
    Line l1{2, 3};
    Line l2{3, 5};
    Line l3{1, 2}; //success for insertion
    Line l4{4, 6}; //fail for insertion b/c of insersection


    auto ret = s.insert(l2);
    cout << "insert 3->5 ";
    if (ret.second) cout << "success " << endl;
    else cout << "fail " << endl;

    ret = s.insert(l3);
    cout << "insert 1->2 ";
    if (ret.second) cout << "success " << endl;
    else cout << "fail " << endl;

    ret = s.insert(l1);
    cout << "insert 2->3 ";
    if (ret.second) cout << "success " << endl;
    else cout << "fail " << endl;

    ret = s.insert(l4);
    cout << "insert 4->6 ";
    if (ret.second) cout << "success " << endl;
    else cout << "fail " << endl;

    return 0;
}

Output:
insert 3->5 success
insert 1->2 success
insert 2->3 success
insert 4->6 fail
set finally contains: 1->2, 2->3, 3->5,

There is something still puzzling to me:

1) Why is simply comparing a.up <= b.down enough to detect overlapping intervals?

Shouldn't we do something like standard approach of detecting interval overlapping?

max(a.down, b.down) < min(a.up, b.up)

2) The 3rd step is not clear to me

insert 3->5 success
insert 1->2 success //OK, b/c 2 <= 3, a.up <= b.down return true
insert 2->3 success //Why success? 3 > 1, i.e., a.up > b.down, return false; does it only compare with interval 3->5?

3) Why does below code not work for removing overlapping intervals?

    auto cmp_set = [](const Line& a, const Line& b) {
        if (max(a.down, b.down) < min(a.up, b.up)) return 0; //standard way to detect overlapping of intervals
        else { //sort the two intervals 
            if(a.up <= b.down) return -1;
            else return 1;
        }
    };

1) Why is simply comparing a.up <= b.down enough to detect overlapping intervals?

[a.down, a.up[ overlaps [b.down, b.up[ when max(a.down, b.down) < min(a.up, b.up) which is equivalent to a.down < b.up && b.down < a.up (remember that we also have a.down <= a.up && b.down <= b.up from interval definition).

We can also list possibilities:

  • a.down < a.up < b.down < b.up (a < b)
  • a.down < b.down < a.up < b.up Intersection
  • a.down < b.down < b.up < a.up Intersection (Totally included)
  • b.down < a.down < a.up < b.up Intersection (Totally included)
  • b.down < a.down < b.up < a.up Intersection
  • b.down < b.up < a.down < a.up (b < a)

The 3rd step is not clear to me

insert 3->5 success insert 1->2 success //OK, b/c 2 <= 3, a.up <= b.down return true insert 2->3 success //Why success? 3 > 1, ie, a.up > b.down, return false; does it only compare with interval 3->5?

Line l1{2, 3};
Line l2{3, 5};
Line l3{1, 2};
Line l4{4, 6};

To insert l1 in {l3, l2}

  • l1 < l2 so l1 is before l2
  • !(l1 < l3) so l1 is not before l3
  • l3 < l1 so l1 is after l3 -> {l3, l1, l2}

For l4 in {l3, l1, l2} We have:

  • !(l4 < l2) (similarly for l3 and l1 ) so l4 is not before l2
  • !(l2 < l4) so l4 is not after l2

we have both !(l2 < l4) && !(l4 < l2) so there are equivalent , we don't insert l4 .

3) Why does below code not work for removing overlapping intervals?

I don't understand where you use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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