2017-08-17 22 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