代表软件包安装和系统依赖关系的最佳数据结构
Best Data Structure representing Package Installation and System Dependencies
我正在尝试创建一个基于面试过程的程序(我选择Java,但可以是C/C++或GoLang(,以表示/模拟软件包安装和系统依赖关系,就像Linux/Unix环境中存在的那样。 基本上,我将满足以下要求:
1( 维护已安装软件包及其依赖项的记录。
2( 支持显式安装软件包以响应命令(除非已安装(。
3( 如果需要安装另一个软件包,则支持隐式安装一个软件包。
4( 支持显式删除包以响应命令(如果不需要支持其他包(。
5( 如果不再需要某个包来支持另一个组件,则支持隐式删除该包。
在安装包之前,自动安装它需要的所有包。 在删除包之前,请确认没有其他包需要它。必须先手动删除依赖包,然后才能删除包。
我想要最好的数据结构(以及我可以检查的链接(的提示,我可以用来做到这一点。我尝试使用队列列表作为存储依赖项的一种方式和一个队列来存储已安装的软件包,但我不确定这是否是最好的方法,例如:
...
ArrayList<Queue<String>> dependencies = new ArrayList<>(capacity);
Queue<String> pkgInstalled = new LinkedList<String>();
...
该过程将从用户捕获条目数据,直到 END 命令。 命令语法为:
依赖项目1 项目2 项目(n(:包裹项目1取决于包裹项目2(和项目3或任何;
安装item1:安装 item 1 和 item 1 所需的任何其他软件包。
删除项目 1:删除项目 1,如果可能,删除项目 1 所需的包。
列表:列出所有当前安装的软件包的名称。
END:标记输入的结束(当单独用于一行中时(。
1( 按照每个回显的"安装"或"删除"行执行响应时执行的操作,确保操作按正确的顺序给出。
2( 对于 LIST 命令,显示当前安装的组件的名称。
3( 对于 DEPEND 和 END 命令,除了回显之外,不会产生任何输出。
4( 对于 DEPEND 命令,每个项目只有一个依赖项列表。
我不知道Queue
在这个练习(或LinkedList
(中的价值,因为您将希望能够随机访问包的依赖项。
我会建议
Map<String, Set<String>> dependsOn = new HashMap<>();
Map<String, Set<String>> requiredBy = new HashMap<>();
这样,当你删除一个包时,你可以找到它拉入的所有包(dependsOn.get(packageToDelete)
(,并从requiredBy
中的每个条目中删除packageToDelete
;如果这让requiredBy
集为空,那么也可以删除该包。
我还建议在添加新的根包时,使用Set
来添加依赖包。 处理它们的顺序并不重要,快速和避免重复更有用。
最初,我认为使用唯一的完全限定包名称作为键会更简单 - 更容易编码和调试。 这需要一种方法来根据包的名称查找包,但这应该已经存在。 但是,如果您愿意,可以为Package
类实现equals()
和hashcode()
,并直接将它们用作Map
键。
为了阐明这可能是如何工作的,下面是一个示例:
public Set<String> addDependencies(Item pkg, Item... dependencies) {
Set<String> pkgDependsOn = dependsOn.get(pkg.getFullyQualifiedName());
if (pkgDependsOn == null) {
pkgDependsOn = new HashSet<>();
dependsOn.put(pkg.getFullyQualifiedName(), pkgDependsOn);
}
pkgDependsOn.addAll(Stream.of(dependencies).map(dep -> dep.getFullyQualifiedName()).collect(Collectors.toSet()));
return pkgDependsOn;
}
(我可能改用Map.merge()
,但在写出来后,我认为它足够复杂,令人困惑。
返回生成的依赖项Set
可能是矫枉过正的,但我可以想象在某些情况下它可能很有用。
如果您选择使用包本身作为密钥,则如下所示:
public Set<Item> addDependencies(Item pkg, Item... dependencies) {
Set<Item> pkgDependsOn = dependsOn.get(pkg);
if (pkgDependsOn == null) {
pkgDependsOn = new HashSet<>();
dependsOn.put(pkg, pkgDependsOn);
}
pkgDependsOn.addAll(Arrays.asList(dependencies));
return pkgDependsOn;
}
我也没有进行错误检查(例如,如果您使包依赖于自身(,空检查等。
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在c代码之间共享数据的最佳方式
- 使用std::source_location报告错误的最佳实践
- 派生类销毁的最佳实践是什么
- 将寄存器设计成可由C和C++访问的外设的最佳实践
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 在C++中向零方向近似的最佳方法
- C++GTKMM gui循环依赖关系
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 检测win32服务创建和删除的最佳方法
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 用于存储分组关系和支持外观的最佳数据结构
- 代表软件包安装和系统依赖关系的最佳数据结构
- "Has a" C++关系,最佳做法是让一个类"implement"多个抽象基类?
- C++ - 解决头文件中模板化类循环依赖关系的最佳约定?