2017-03-04 7 views
0

このコードはかなり神経質になっています。しばらくの間それをデバッグしていた、私はC++にどのようにしているかを信じていません。ストラクチャフォワードリスト項目が消滅しますか?

私はいくつかの単純なアルゴリズムを実行するためにグラフをモデル化しようとしていますが、うまくいかないようです。すべての頂点には、近隣の要素への順方向リストが含まれていますが、要素を挿入するときは明らかに存在します。その時、フォワードリストは空です。スコープが...ん運のいずれか。..既存の頂点への参照を維持するために、グラフを修正

#include <iostream> 
#include <vector> 
#include <set> 
#include <forward_list> 
#include <fstream> 

using namespace std; 

typedef struct Vertex Vertex; 

struct Vertex { 
    unsigned id; 
    forward_list<Vertex*>_next; 

    bool operator < (const Vertex &other) const { return id < other.id; }; 
}; 

typedef set<Vertex> Graph; 
typedef vector<Vertex*> Index; 
typedef pair<unsigned, unsigned> Edge; 
typedef forward_list<Vertex*> Neighbors; 


// Function: process_line() 
// Purpose:  process a specific line from the file. 
// Params:  line to process 
Edge process_line(string line){ 
    unsigned vertex_from; 
    unsigned vertex_to; 

    int idx = line.find(" "); 

    vertex_from = (unsigned)stoul(line.substr(0, idx)); 
    vertex_to = (unsigned)stoul(line.substr(idx+1, line.length())); 

    return make_pair(vertex_from, vertex_to); 
} 


// Function: load_graph() 
// Purpose:  load graph from file in relation 
// Params:  path, and reference to graph and index 
bool load_graph(string file_path, Graph &graph, Index &index){ 
    string line; 
    ifstream file(file_path); 
    bool foundEmptyLine = false; 

    if(file.is_open()){ 
     while(getline(file, line)){ 
      if(line.empty()){ 
       foundEmptyLine = true; 
       continue; 
      } 

      if(!foundEmptyLine){ 
       // processing vertexes 
       Vertex *vertex = new Vertex; 

       vertex->id = stoul(line); 
       graph.insert(*vertex); 
       index.emplace_back(vertex); 
      }else{ 
       //Processing relations 
       Edge edge = process_line(line); 

       Vertex* neighbor = index.at(edge.second); 
       Vertex* source = index.at(edge.first); 

       // Lookup edge in index 
       source->_next.emplace_front(neighbor); 

       // ITEMS PRESENT! <---------------------- 
      } 
     } 
     file.close(); 
    }else{ 
     cout << "Unable to open " << file_path; 
     return false; 
    } 

    return true; 
} 


void print_graph(Graph &graph){ 
    for(Graph::iterator it = graph.begin(); it != graph.end(); ++it){ 
     Neighbors neighs = it->_next; 

     cout << "Node: " << it->id << " neighbors: " neighs.empty(); 

     cout << endl; 
    } 
} 


// Entry point. 
int main() { 
    Graph graph; 
    Index index; 

    load_graph("graph_1.txt", graph, index); 
    print_graph(graph); 
} 

答えて

1

これはもう一度昨日と同じ問題です。

std::setのC++ 11 iteratorは常にconst value_typeにイテレータであるので、のはstd::set

  • を再現してみましょう。これは、std::setのエントリを変更するときに、このエントリをデータ構造のどこかに配置する必要があるためです。
  • 我々はstd::setに何かを挿入すると、2人の署名が提供されています:

    pair<iterator,bool> insert (const value_type& val); 
    pair<iterator,bool> insert (value_type&& val); 
    

    しかし、いずれにしても挿入コピーまたは移動要素容器の中に。

は、だからあなたの場合、あなたは(あなたが削除したことがない方法で!あなたはvalgrindのを使用して確認することができ、多くのメモリをリークします)メモリを割り当てる

Vertex *vertex = new Vertex; 
vertex->id = stoul(line); 
graph.insert(*vertex); 
index.emplace_back(vertex); 

最初に行うとき。次に、頂点のコピーをstd::setに挿入し、割り当てられたメモリのポインタをstd::vectorに挿入します。

あなたは、後であなたのベクトルから頂点を取る

Vertex* neighbor = index.at(edge.second); 
Vertex* source = index.at(edge.first); 

// Lookup edge in index 
source->_next.emplace_front(neighbor); 

を行う(これはあなたがnewに割り当てられた頂点である、覚えておいてください)。そして、std::forward_listに別の頂点(動的に割り当てられたもの)を挿入します。 しかし、:彼らはあなたのstd::setにある頂点とは関係ありません。

あなたはその後、あなたのstd::setを通過するときに:

for (Graph::iterator it = graph.begin(); it != graph.end(); ++it) 

これはエッジを挿入するときにするときに何をしたかとは全く無関係である - そして、すべてのstd::forward_list sが空になっています。

サイドノート:

  • これは、あなたがCではなく、C++で使用していたものです!

    typedef struct Vertex Vertex; 
    
  • この1あなたは、上記配置する必要があります:

    typedef forward_list<Vertex*> Neighbors; 
    

    あなたが_nextを宣言した後_nextこのタイプを持っているので、それはNeighborsの型を宣言しても意味がありません。

  • 使用const whereeverすることができます、とcbegin/cendあなたは例えば、(私はすでに昨日あなたにこのことを告げた)ことができwhereever:

    for(Graph::iterator it = graph.cbegin(); it != graph.cend(); ++it){ 
    

    それはここに違いはありませんが、あなたが変更した場合いくつかの点での種類、begin()ではなくconst value_type

+0

value_typeにイテレータを返す可能性がもう一度あなたの努力をありがとうございました。私はセットがベクトルに対抗する要素をコピーするという事実を忘れてしまった。それで、なぜリファレンスをセットに挿入すると全体が機能するのですか?私の作業バージョンでもconst_iteratorのヒントを使用しました。 – Iso

+0

インデックスにベクトルを使用し、グラフにはを、近隣にはforward_list を設定することをおすすめします。 – overseas

0

それについて解明することができなかったとして

私は、新しいaswellを使用してforward_listを配分しようとしました。私はまだこれがなぜ固定されているのかは分かりませんが、ヘッドアップを与えるように感じました。

関連する問題