2012-04-04 5 views
1

私はグラフアルゴリズムを実装しようとしていたので、テストを続けるとGNU C++コンパイラ(セグメンテーションフォルト)でエラーが発生しました。 Visual Studioで私は原因が "ベクトル反復子互換性がありません"見た。しかし、これはどうやって起こる?このエラーは、訪問者オブジェクトのフィールドにアクセスしようとすると、 "getName()"行のshortPathPathBFS関数でスローされます。 VisitorはVertice *キューの要素なので、キューのイテレータに依存してはいけません。理由を説明できるなら、私は感謝します。ベクトルイテレータが互換性がない(セグメンテーションフォルト)

for(vector<Vertice*>::iterator it = (visitor->getNeighbors()).begin(); it != (visitor->getNeighbors()).end(); it++) 

問題は、次の2個の異なるコンテナ(コンテナが同じタイプであっても)からのイテレータを比較することはできませんということですが、新しいのvisitor->getNeighbors()返します

#include <queue> 
#include <stack> 
#include <vector> 
#include <set> 
#include <string> 
#include <iostream> 

using namespace std; 

//#define traverse(container,iterator) \ 
//for(typeof(container.begin()) iterator = container.begin(); iterator != container.end(); iterator++) 

class Edge; 
class Vertice 
{ 
private: 
    string name; 
    vector<Edge*> incidences; 
    bool visited; 
public: 
    Vertice() {name = "NULL"; visited = false;} 
    Vertice(string name) {this->name = name; visited = false;} 
    void setName(string name) {this->name = name;} 
    string getName() {return name;} 
    bool isVisited() {return visited;} 
    void setVisited() {visited = true;} 
    void setUnvisited() {visited = false;} 
    void connectTo(Vertice*); 
    void connectTo(Vertice*,int); 
    void printNeighbors(); 
    vector<Vertice*> getNeighbors(); 
}; 

class Edge 
{ 
private: 
    int cost; 
    Vertice *start,*end; 
public: 
    friend class Vertice; 
    Edge() {cost = 0;} 
    Edge(Vertice * start, Vertice * end) {this->start = start; this->end = end;} 
    Edge(Vertice * start, Vertice * end, int cost) 
    {this->start = start; this->end = end; this->cost = cost;} 
    Vertice* getEnd() {return end;} 
    Vertice* getStart() {return start;} 
}; 

void Vertice::connectTo(Vertice * w) 
{ 
    incidences.push_back(new Edge(this,w)); 
} 

void Vertice::connectTo(Vertice* w,int cost) 
{ 
    incidences.push_back(new Edge(this,w,cost)); 
} 

vector<Vertice*> Vertice::getNeighbors() 
{ 
    vector<Vertice*> temp; 
    for(vector<Edge*>::iterator it = incidences.begin(); it != incidences.end(); it++) 
    { 
     temp.push_back((*it)->getEnd()); 
    } 
    return temp; 
} 

void Vertice::printNeighbors() 
{ 
    for (vector<Edge*>::iterator i=incidences.begin(); i!= incidences.end(); i++) 
    { 
     cout<<(*i)->start->getName()<<"--"<<(*i)->cost<<"--"<<(*i)->end->getName()<<endl; 
    } 
} 

class Graph 
{ 
public: 
    // using set for non-comparable elements are not good 
    // but this is for exercising 
    set<Vertice *> vertices; 
public: 
    void initGraph() 
    { 
     Vertice *v; 
     v = new Vertice("IST");vertices.insert(v); 
     v = new Vertice("ANK");vertices.insert(v); 
     v = new Vertice("IZM");vertices.insert(v); 
     v = new Vertice("BER");vertices.insert(v); 
     v = new Vertice("TOR");vertices.insert(v); 
     v = new Vertice("BEJ");vertices.insert(v); 
     v = new Vertice("PER");vertices.insert(v); 

     (*findByName("IST"))->connectTo(*findByName("ANK"),10); 
     (*findByName("IST"))->connectTo(*findByName("IZM"),5); 
     (*findByName("IST"))->connectTo(*findByName("BER"),61); 

     (*findByName("IZM"))->connectTo(*findByName("ANK"),3); 
     (*findByName("IZM"))->connectTo(*findByName("TOR"),98); 
     (*findByName("IZM"))->connectTo(*findByName("BER"),70); 

     (*findByName("BER"))->connectTo(*findByName("ANK"),59); 
     (*findByName("BER"))->connectTo(*findByName("TOR"),91); 

     (*findByName("ANK"))->connectTo(*findByName("PER"),77); 
     (*findByName("ANK"))->connectTo(*findByName("BEJ"),151); 

     (*findByName("BEJ"))->connectTo(*findByName("TOR"),48); 
     (*findByName("TOR"))->connectTo(*findByName("ANK"),100); 
     (*findByName("PER"))->connectTo(*findByName("BEJ"),162); 
     (*findByName("TOR"))->connectTo(*findByName("PER"),190); 
     (*findByName("BEJ"))->connectTo(*findByName("PER"),163); 
    } 

    set<Vertice*>::iterator findByName(string name) 
    { 
     for(set<Vertice*>::iterator it = vertices.begin(); it != vertices.end(); it++) 
     { 
      if ((*it)->getName() == name) 
      { 
       return it; 
      } 
     } 
     return vertices.end(); 
    } 

    int shortestPathBFS(Vertice * start, Vertice * finish) 
    { 
     queue<Vertice *> q; 
     q.push(start); 

     Vertice *visitor; 
     while(!q.empty()) 
     { 
      visitor = q.front();q.pop(); 
      visitor->setVisited(); 
      cout<<"BFS : "<<visitor->getName()<<endl; 
      if (visitor->getName() == finish->getName()) 
      { 
       break; 
      } 
      for(vector<Vertice*>::iterator it = (visitor->getNeighbors()).begin(); it != (visitor->getNeighbors()).end(); it++) 
      { 
       if (!(*it)->isVisited()) 
       { 
        q.push((*it)); 
       } 
      } 
     } 
     return 0; 
    } 

    void printAll() 
    { 
     for(set<Vertice*>::iterator it = vertices.begin(); it != vertices.end(); it++) 
     { 
      (*it)->printNeighbors(); 
     } 
    } 
}; 

int main(int argc, char **argv) 
{ 
    Graph g; 
    g.initGraph(); 
    g.printAll(); 
    g.shortestPathBFS(*(g.findByName("IST")),*(g.findByName("PER"))); 

    return 0; 
} 

答えて

2

犯人はGraph::shortestPathBFSで、このラインでありますそれが呼び出されるたびにオブジェクトを返します。その結果、あるオブジェクトからitが初期化され、別のオブジェクトのイテレータと比較されます。

としてループを書き直し

vector<Vertice*> neighbors = visitor->getNeighbors(); 
for(vector<Vertice*>::iterator it = neighbors.begin(); it != neighbors.end(); ++it) 
{ 
    if (!(*it)->isVisited()) 
    { 
     q.push((*it)); 
    } 
} 
関連する問題