我必须为有向图实现一个类,我需要检索与边相关的成本以及在O(1)中插入/更改成本。 使用std :: map很好,唯一的问题是它对于指定的需求平均需要O(logn),所以我看了一眼std :: unordered_map并尝试在我的程序中使用它。唯一的问题是我不太了解编译错误。
这些是我尝试访问unordered_map的行(试过[]以及.insert或.find,仍然不起作用)
void DirectedGraph::setValueOfMapEdge(int node1, int node2, int cost) {
mapEdges.insert({{node1, node2}, cost});
}
int DirectedGraph::getValueOfMapEdge(int node1, int node2) {
return mapEdges[make_pair(node1, node2)];
}
这是错误日志https://hastebin.com/qawamosuso.vbs
这是完整的代码(抱歉缺少评论)
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
class DirectedGraph {
public:
DirectedGraph() {
noVertices = 0;
outboundEdges = inboundEdges = vector<vector<int>>();
}
void readFromFile(string fileName);
void setNoVertices(int vertices);
void addEdge(int node1, int node2);
void setValueOfMapEdge(int node1, int node2, int cost);
int getValueOfMapEdge(int node1, int node2);
void resizeGraph(int noVertices);
bool isEdgeBetweenNodes(int node1, int node2);
int getInDegree(int node);
int getOutDegree(int node);
int getNoVertices();
vector<int> getOutboundNeighboursVector(int node);
vector<int> getInboundNeighboursVector(int node);
friend class VertexIterator;
private:
int noVertices;
vector<vector<int>> outboundEdges;
vector<vector<int>> inboundEdges;
unordered_map<pair<int,int>, int> mapEdges;
vector<int> inDegree, outDegree;
};
class VertexOutboundIterator {
public:
VertexOutboundIterator(DirectedGraph *directedGraph, int node) {
graph = directedGraph;
vertex = node;
}
void first();
void next();
bool isDone();
int currentItem();
private:
DirectedGraph *graph;
int vertex;
int index;
};
void VertexOutboundIterator::first() {
index = 0;
}
void VertexOutboundIterator::next() {
++index;
}
bool VertexOutboundIterator::isDone() {
return index == graph->getOutboundNeighboursVector(vertex).size();
}
int VertexOutboundIterator::currentItem() {
return graph->getOutboundNeighboursVector(vertex)[index];
}
class VertexInboundIterator {
public:
VertexInboundIterator(DirectedGraph *directedGraph, int node) {
graph = directedGraph;
vertex = node;
}
void first();
void next();
bool isDone();
int currentItem();
private:
DirectedGraph *graph;
int vertex;
int index;
};
void VertexInboundIterator::first() {
index = 0;
}
void VertexInboundIterator::next() {
++index;
}
bool VertexInboundIterator::isDone() {
return index == graph->getInboundNeighboursVector(vertex).size();
}
int VertexInboundIterator::currentItem() {
return graph->getInboundNeighboursVector(vertex)[index];
}
vector<int> DirectedGraph::getInboundNeighboursVector(int node) {
return inboundEdges[node];
}
vector<int> DirectedGraph::getOutboundNeighboursVector(int node) {
return outboundEdges[node];
}
void DirectedGraph::readFromFile(string fileName) {
ifstream fin(fileName);
int noVertices = 0, noEdges = 0;
fin >> noVertices >> noEdges;
setNoVertices(noVertices);
resizeGraph(noVertices);
int x, y, c;
for ( int i = 0; i < noEdges; ++i ) {
fin >> x >> y >> c;
DirectedGraph::addEdge(x,y);
DirectedGraph::setValueOfMapEdge(x,y,c);
}
}
void DirectedGraph::setNoVertices(int vertices) {
noVertices = vertices;
}
void DirectedGraph::resizeGraph(int noVertices) {
outboundEdges = inboundEdges = vector<vector<int>>(noVertices);
inDegree = outDegree = vector<int>(noVertices);
}
void DirectedGraph::addEdge(int node1, int node2) {
outboundEdges[node1].push_back(node2);
inboundEdges[node2].push_back(node1);
inDegree[node2]++;
outDegree[node1]++;
}
void DirectedGraph::setValueOfMapEdge(int node1, int node2, int cost) {
mapEdges.insert({{node1, node2}, cost});
}
int DirectedGraph::getValueOfMapEdge(int node1, int node2) {
return mapEdges[make_pair(node1, node2)];
}
int DirectedGraph::getNoVertices() {
return noVertices;
};
bool DirectedGraph::isEdgeBetweenNodes(int node1, int node2) {
for ( const auto node : outboundEdges[node1] )
if (node == node2)
return true;
return false;
}
int DirectedGraph::getInDegree(int node) {
return inDegree[node];
}
int DirectedGraph::getOutDegree(int node) {
return outDegree[node];
}
int main() {
DirectedGraph g = DirectedGraph();
g.readFromFile("1.txt");
/*cout << g.isEdgeBetweenNodes(2,0) << '\n';
cout << g.getOutDegree(2) << '\n';
VertexOutboundIterator vt = VertexOutboundIterator(&g, 2);
for ( vt.first(); !vt.isDone(); vt.next() ) {
cout << vt.currentItem() << '\n';
}
VertexInboundIterator ivt = VertexInboundIterator(&g, 3);
for ( ivt.first(); !ivt.isDone(); ivt.next() )
cout << ivt.currentItem() << '\n'; */
cout << g.getValueOfMapEdge(0, 1);
return 0;
}
我正在使用g ++,该版本支持c ++ 11。 任何想法都会非常感激。
答案 0 :(得分:2)
您使用std::pair
作为密钥。对于std::unordered_map
,需要使用std::hash
对密钥进行哈希处理,std::pair
没有专门化。
虽然Boost hash library有它,除非你想自己做这样的专业化。