表示包安装和系统依赖性的最佳数据结构

时间:2018-05-31 21:01:41

标签: java c++ c go data-structures

我正在尝试创建一个程序(我选择Java但可以是C / C ++或GoLang),基于访谈过程来表示/模拟Linux安装和系统依赖性,如Linux / Unix环境中存在的那样。 基本上,我会遵循以下要求:

1)维护已安装软件包及其依赖项的记录 2)支持显式安装包以响应命令(除非它已经安装) 3)如果需要安装另一个软件包,则支持隐式安装软件包 4)支持显式删除包以响应命令(如果不需要支持其他包) 5)如果不再需要支持另一个组件,则支持隐式删除包。

在安装软件包之前,请自动安装所需的所有软件包。 在删除软件包之前,请确认没有其他软件包需要它。在删除软件包之前,必须手动删除相关软件包。

我想了解我可以使用的最佳数据结构(以及我可以检查的链接)的提示。我尝试使用队列列表作为存储依赖项的方法,使用队列来存储已安装的软件包,但我不确定这是否是最好的方法,如:

...
ArrayList<Queue<String>> dependencies = new ArrayList<>(capacity);
Queue<String> pkgInstalled = new LinkedList<String>();
...

该过程将捕获用户的输入数据,直到END命令。 命令语法为:

DEPEND item1 item2 item(n):包item1取决于包item2(以及item3或any;

INSTALL item1:安装item1和item1所需的任何其他包。

删除第1项:删除第1项,如果可能,删除第1项所需的包。

LIST:列出所有当前安装的软件包的名称。

END:当在一行中单独使用时,标记输入的结尾。

1)按照每个回显的INSTALL或REMOVE行跟踪响应中采取的动作,确保以正确的顺序给出动作。
2)对于LIST命令,显示当前安装的组件的名称 3)对于DEPEND和END命令,不产生除echo之外的输出 4)对于DEPEND命令,每个项目只有一个依赖项列表。

1 个答案:

答案 0 :(得分:0)

我不知道此练习(或Queue)中LinkedList的值,因为您希望能够随机访问包的依赖关系。< / p>

我建议

Map<String, Set<String>> dependsOn = new HashMap<>();
Map<String, Set<String>> requiredBy = new HashMap<>();

这样,当您删除某个包时,您可以找到它所引入的所有包(dependsOn.get(packageToDelete))并从packageToDelete中的每个条目中删除requiredBy;如果将requiredBy设置为空,则也可以删除该包。

我还建议在添加新的根包时使用Set添加依赖包。你处理它们的顺序并不重要,快速避免重复更有用。

最初我认为使用独特的完全限定包名作为键会更简单 - 更容易编码和调试。这需要一种基于名称查找包的方法,但这应该已经存在。但是,如果您愿意,可以为equals()课程实施hashcode()Package,并将其直接用作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;
}

我也没有进行错误检查(比如你是否依赖自己),空检查等等。