题目:编译顺序
给你一个系列的项目project和一系列依赖关系(依赖关系dependencies为一个链表,其中每一个元素为两个项目的编组,且第二项目依赖于第一个项目)。所有项目的依赖项必须在该项目被编译前编译。请找出可以使得所有项目顺利编译的顺序。如果没有合法的编译顺序,返回错误。
示例:
输入:
projects:a,b,c,d,e,f
dependencies:(a,b),(f,b),(b,d),(f,a),(d,c)
输出:f,e,a,b,d,c
一、思路
将所有信息表示为一个图。请注意图中箭头的方向。下图中,从d指向g的箭头表示d必须在g之前进行编译。
(1)首先加入没有入边的节点。如果一系列项目可以被编译,那么其中必定包含一些”起始“项目,这些项目不应该有依赖项。如果一个项目没有依赖项(入边),则可以确定首先编译该项目不会有问题
(2)从根节点移除了所有的出边。
(3)在这之后,找到此时没有入边的节点。
(4)如果存在剩余的节点且其都包含依赖项,该怎么办,这说明该系统无法进行编译!
二、解法
1.迭代法
代码如下:
class Project{
public:
vector<Project*> children;
unordered_map<string, Project*> m_map;
string name;
int dependencies = 0;
enum State{
COMPLETE,
PARTIAL,
BLANK
};
State state;
Project(string n){
name = n;state = State::BLANK;}
void addNeighbor(Project *node){
if(!m_map.count(node->name)){
children.push_back(node);
m_map.insert(make_pair(node->name, node));
node->dependencies++;
}
}
};
class Graph{
public:
vector<Project*> nodes;
unordered_map<string, Project*> m_map;
Project* getOrCreateNode(string &name){
if(!m_map.count(name)){
Project* node = new Project(name);
nodes.push_back(node);
m_map.insert(make_pair(name, node));
}
return m_map[name];
}
void addEdge(string startName, string endName){
Project* start = getOrCreateNode(startName);
Project* end = getOrCreateNode