从c ++中的集合中擦除时的分段错误

时间:2017-08-17 07:29:16

标签: c++ stl computational-geometry

eq是事件队列,其中每个元素的形式为e =(F =(int,double),S =(int,double))。 当我在事件队列中处理事件e =(F,S)时,我插入或删除或从set< pair<int, double> > el插入e.S。在删除e.S时,您可以假设e.S已经在el

但是,当我尝试从e.S el删除el.erase(e.S)时,它会出错:

  

分段错误11

请帮助。

#include <iostream>
#include <vector>
#include <cmath>
#include <queue>
#include <climits>
#include <set>

#define MP make_pair
#define PB push_back
#define F first
#define S second
#define OUT cout <<
#define IN cin >>
#define newline cout << "\n"
#define space cout << " "
#define fastIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define PI 3.14159265
#define EPSILON 1e-9
#define OBJ pair<int, double>
#define EVENT pair< OBJ, OBJ >

using namespace std;

struct point {
    int x, y;
};

double angle(double x, double y) {
    double t = atan2 (y, x) * 180.0 / PI;
    return t >= 0 ? t : 360 - fabs(t);
}

vector< struct point > vp;

struct COMP {
    bool operator()(const EVENT &p, const EVENT &q) {
        if(fabs(p.F.S - q.F.S) > EPSILON) {
            return p.F.S < q.F.S;
        }
        else if(p.F.F != q.F.F) return p.F.F == 0;
        else return p.S.S < q.S.S;
    }
} comp_eq;

vector< EVENT > eq;

class comp_el {
public:
    bool operator()(const OBJ &p, const OBJ &q) {
        if(fabs(p.S - q.S) > EPSILON) {
            return p.S < q.S;
        }
        else {
            double a_p = angle(vp[p.F].y, vp[p.F].x), a_q = angle(vp[q.F].y, vp[q.F].x);
            if(fabs(a_p - a_q) > EPSILON) return a_p < a_q;
            else return false;
        }
    }
};

set< OBJ, comp_el > el;

int main() {
    int n, r;
    double theta, phi, d, beg, end;
    vector<struct point> vp;
    struct point p;
    while(1) {
        IN n;
        if(n == 0) break;
        eq.clear();
        vp.clear();
        for(int j = 0; j < n; j++) {
            IN p.x;
            IN p.y;
            IN r;
            vp.PB(p);
            d = sqrt(p.x * p.x + p.y * p.y);
            theta = angle(p.y, p.x);
            phi = asin(r/d);
            beg = theta - phi;
            beg = beg < 0 ? 360 - fabs(beg) : beg;
            eq.PB(MP(MP(0, beg), MP(j, d)));
            if(fabs(beg - 0) < EPSILON) {
                eq.PB(MP(MP(0, 360), MP(j, d)));
                eq.PB(MP(MP(1, 360), MP(j, d)));
            }
            end = beg + 2 * phi;
            if(fabs(end - 360) > EPSILON) {
                if(end > 360) {
                    eq.PB(MP(MP(1, 360), MP(j, d)));
                    eq.PB(MP(MP(0, 0), MP(j, d)));
                    eq.PB(MP(MP(1, end - 360), MP(j, d)));
                }
                else eq.PB(MP(MP(1, end), MP(j, d)));
            }
            else {
                eq.PB(MP(MP(1, 360), MP(j, d)));
                eq.PB(MP(MP(0, 0), MP(j, d)));
                eq.PB(MP(MP(1, 0), MP(j, d)));
            }
        }
        sort(eq.begin(), eq.end(), comp_eq);


        //I NEED HELP IN THE PART BELOW.


        for(int j = 0; j < eq.size(); j++) {
            EVENT e = eq[j];
            OUT e.F.F;
            space;
            OUT e.F.S;
            space;
            OUT e.S.F;
            space;
            OUT e.S.S;
            space;
            newline;
        }
        double maxD = -INT_MAX;
        for(int j = 0; j < eq.size(); j++) {
            EVENT e = eq[j];
            if(e.F.F == 0) {
                el.insert(e.S);
            }
            else {
                el.erase(e.S);
            }
            set< OBJ >::iterator first = el.begin();
            // for(; first != el.end(); first++){
            //  OUT (*first).F; space; OUT (*first).S;
            // }
            // newline;
            if(first != el.end()) {
                OUT (*first).F;
                space;
                OUT (*first).S;
                newline;
                if((*first).S > maxD) maxD = (*first).S;
            }
        }
        OUT maxD;
        newline;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

comp_el尝试查找全局变量vp中的元素 - 但该向量始终为空。 main()代替填充一个局部变量,该变量恰好也被命名为vp,但与全局vp不同且不相关。然后,您的程序通过访问索引超出范围的向量元素来展示未定义的行为。

另请注意,比较器基于&#34;足够接近&#34;几乎相等(如{,1 {}})通常不满足严格弱序的要求。这种比较器引起的等价关系不具有传递性:可以找到三个元素fabs(p.F.S - q.F.S) > EPSILONAB,使C足够接近A }和B足够接近B,但CA不够接近。