2017-08-17 21 views
-2

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

但是,当我试图通过el.erase(e.S)el删除e.S它给出了一个错误:

segmentation fault 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; 
} 
+2

为什么你定义make_pair到MP,push_back到PB等等?在我看来,这是非常糟糕的风格。它并没有真正帮助更快地编写代码,但使其阅读代码的难度增加了100倍。 push_back(make_pair(Foo))组合应该被缩减为emplace_back(Foo)。 –

+1

当你用调试器逐行执行代码时,你观察到了什么? – user0042

+0

'beg = theta-phi'没什么意义:'theta'是度数,但phi'是弧度。 –

回答

0

comp_el尝试查找元素在全局变量vp - 但是,向量总是空空的。 main()改为填充局部变量,该局部变量碰巧也被命名为vp,但与全局vp不同并与之无关。您的程序会通过访问索引超出范围的向量元素来展现未定义的行为。


还要注意的是基于比较“足够接近”几乎相等(如,fabs(p.F.S - q.F.S) > EPSILON)一般不符合严格的弱序化的要求。等价关系这样的比较导致不传递:这是有可能找到三个要素ABC这样A是足够接近BB足够接近C,但A没有足够接近C