【vivo 2021秋スクール募集】 1.コンパイル依存問題
完全なソフトウェア プロジェクトには、コードとドキュメントで構成される多数のソース ファイルが含まれることがよくあります。コンパイラがプロジェクト全体をコンパイルするとき、依存関係に従って各ソース ファイルを順番にコンパイルする必要がある場合があります。
たとえば、A.cpp が B.cpp に依存している場合、コンパイル中に、コンパイラは A.cpp をコンパイルする前に、まず B.cpp をコンパイルする必要があります。
ファイル 0、1、2、3 の 4 つのファイルがあるとします。ファイル No.0 はファイル No.1 に依存し、ファイル No.1 はファイル No.2 に依存し、ファイル No.3 はファイル No.1 に依存します。ソース ファイルのコンパイル順序は 2,1,0 ,3 または 2,1,3,0 です。
ファイルの依存関係は 1,2,-1,1 のようになります。これは、ファイル No.0 はファイル No.1 に依存し、ファイル No.1 はファイル No.2 に依存し、ファイル No.2 はファイル No.2 に依存しないことを意味します。依存関係があり、ファイル No. 3 はファイル No. 1 に依存します。完全なプログラムを追加し、正しいコンパイル シーケンスを返してください。複数のファイルを同時にコンパイルできる場合は、1 つのシチュエーションを数値の昇順で返すだけであることに注意してください。たとえば、前述のケースの出力は次のようになります: 2,1,0,3
入力例:
"1,2,-1,1"
出力例:
"2,1,0,3"
答え
優先キュー (小さなルート ヒープ) 処理を使用したトポロジカル ソート: 複数のファイルを同時にコンパイルできる場合、それらのファイルは昇順で返されます。
import java.util.*;
public class Solution {
public String compileSeq(String input) {
String[] fileNum = input.split(",");
int n = fileNum.length;
int[] fileIds = new int[n];
// 小根堆 下标
PriorityQueue<Integer> pq = new PriorityQueue<>();
// 从没有依赖的文件开始,为-1说明该文件id不用前置文件,将id加入堆中
for (int i = 0; i < n; i++) {
fileIds[i] = Integer.parseInt(fileNum[i]);
if (fileIds[i] == -1) {
pq.offer(i);
}
}
//收集结果
StringBuilder sb = new StringBuilder();
// 利用小根堆实现拓扑排序
while (!pq.isEmpty()) {
// 可以先执行的前置文件
int fileId = pq.poll();
sb.append(fileId).append(",");
// 将所有依赖 fileId 的文件加入小根堆
for (int i = 0; i < n; i++) {
if (fileIds[i] == fileId) {
pq.offer(i);
}
}
}
//删除最后一个,
return sb.deleteCharAt(sb.length() - 1).toString();
}
public static void main(String[] args) {
Solution solution = new Solution();
String s = solution.compileSeq("1,2,-1,1");
System.out.println(s);
}
}