我正在处理shortest path problem,这意味着我必须创建一个数据类型或类来模拟我的map。为了做到这一点,我现在使用map<string, map<string, int>>
,其中第一个string
是节点的名称(称为节点A),第二个参数是A连接到它们的节点的映射。到A.的距离。
虽然这很有效,但我觉得处理节点是一种相当麻烦的方式,创建地图比实际算法更耗时。任何人都可以建议在C ++数据结构中优雅地表达this之类的东西吗?
对不起,澄清一下。首先,这两种语法都是可管理的,但是如果有人可以建议更优雅的东西,那么欢迎,迭代地图是非常令人沮丧的,因为我还必须在较大的地图上迭代每个对中的“子地图”。其次,我测量了创建10个节点的映射的时间,并将其与实际算法运行所花费的时间进行了比较,创建然后运行需要更长的时间。
答案 0 :(得分:4)
一个非常简单的方法是......一张桌子。
+---+---+--
| A | B |
+---+---+---+--
| A | 0 |100|
+---+---+---+--
| B |100| 0 |
+---+---+---+--
这可以相当简单地实现,然后你需要设计一种方法来表示没有连接,这可以通过使用sentinel值来完成。
其次,表示节点的方式不够充分。字符串是重量级的野兽。我建议创建一个从真实姓名到简单数字的映射,然后只使用表格中的数字。
例如,您可以使用这样的方法:
class Graph {
public:
Graph() {}
void addEdge(std::string const& left,
std::string const& right,
unsigned weight)
{
unsigned const leftIndex = this->getNode(left);
unsigned const rightIndex = this->getNode(right);
if (_graph.size() <= leftIndex) {
_graph.resize(leftIndex + 1, Sentinel);
}
std::vector<unsigned>& leftEdges = _graph[leftIndex];
if (leftEdges.size() <= rightIndex) {
leftEdges.resize(rightIndex + 1, Sentinel);
}
unsigned& edge = leftEdges[rightIndex];
if (edge != Sentinel) {
std::cerr << "There was already a weight for '"
<< left << "' -> '" << right "'\n";
} else {
edge = weight;
}
}
// Returns (weight, true) if the edge exists and (0u, false) otherwise
std::pair<unsigned,bool> getWeight(std::string const& left,
std::string const& right) const
{
unsigned const leftIndex = this->getNode(left);
unsigned const rightIndex = this->getNode(right);
try {
unsigned const weight = _graph.at(leftIndex).at(rightIndex);
return weight == Sentinel ? std::make_pair(0u, false) :
std::make_pair(weight, true);
} catch(std::out_of_range const&) {
return std::make_pair(0u, false);
}
}
private:
static unsigned const Sentinel = (unsigned)-1;
unsigned getNode(std::string const& node) const {
std::map<std::string, unsigned>::const_iterator it = _nodes.find(node);
return it == _nodes.end() ? _graph.size() : it->second;
}
unsigned getNode(std::string const& node) {
return _nodes.insert(std::make_pair(node, _nodes.size()));
}
std::map<std::string, unsigned> _nodes;
std::vector< std::vector<unsigned> > _graph;
};
当然,如果您直接编码节点并且只处理积分(这将从类中删除所有这些字符串 - >无符号转换)会更简单。
另请注意,我为有向图创建了一个类,如果图不是定向的,则必须在以下选项之间进行选择: