|
|
/*
问题描述: 题目描述: 一个完整的软件项目往往会包含很多由代码和文档组成的源文件。编译器在编译整个项目的时候,可能需要按照依赖关系来依次编译每个源文件。比如,A.cpp 依赖 B.cpp,那么在编译的时候,编译器需要先编译 B.cpp,才能再编译 A.cpp。 假设现有 0,1,2,3 四个文件,0号文件依赖1号文件,1号文件依赖2号文件,3号文件依赖1号文件,则源文件的编译顺序为 2,1,0,3 或 2,1,3,0。现给出文件依赖关系,如 1,2,-1,1,表示0号文件依赖1号文件,1号文件依赖2号文件,2号文件没有依赖,3号文件依赖1号文件。请补充完整程序,返回正确的编译顺序。注意如有同时可以编译多个文件的情况,按数字升序返回一种情况即可,比如前述案例输出为:2,1,0,3
输入例子1: "1,2,-1,1" 输出例子1: "2,1,0,3" */ #include <bits/stdc++.h>
using namespace std;
class Solution { public: string compileSeq(string input) { //首先完成有向无环图的构建
//统计图中各节点的个数 并标记头节点为-1
//使用优先队列 按照先小后大的顺序遍历输出节点值
int len = input.size(); /*********构建有向无环图(指向关系)*********/ map<int, vector<int>> mp;//first为先 second为后, 也就是second依赖于first
string tmp; int idx = 0; for(auto& s:input){ if(s != ',') tmp += s; else{ mp[stoi(tmp)].push_back(idx++); string().swap(tmp);//清空string
} } if(!tmp.empty()) mp[stoi(tmp)].push_back(idx++); /**********统计各节点个数 并保存头节点***********/ vector<int> indexcount(len, 0);//统计各节点个数
priority_queue<int, vector<int>, greater<>> pq;//保存节点
for(auto& m:mp){ if(m.first == -1){ for(auto& a:m.second){ pq.push(a); indexcount[a] = -1; } }else{ for(auto& a:m.second) ++indexcount[a]; } } /************根据指向关系遍历图 并按照优先队列输出结果********/ vector<int> ans; while(!pq.empty()){ int node = pq.top(); pq.pop();//输出了就需要从优先队列中弹出
ans.push_back(node); for(auto& m:mp[node]){ if(--indexcount[m] == 0)//如果该节点是最后一次在图中出现 则放入队列中
pq.push(m); } } /***********输出结果************/ string res; for(auto& i:ans){ res += to_string(i); res.push_back(','); } if(!res.empty()) res.pop_back(); return res; } };
int main(){ Solution OnecompileSeq; string res = OnecompileSeq.compileSeq("1,2,-1,1"); cout << res << endl; return 0; }
|