gpt4 book ai didi

c++ - 如何拓扑排序这个数据结构

转载 作者:搜寻专家 更新时间:2023-10-31 02:20:53 26 4
gpt4 key购买 nike

我正在尝试弄清楚一些依赖性的东西,我走得很远,但现在我被困住了。

假设我有一个这样的数据结构:

map<string, vector<string>> deps;

其中映射中的每个键都是一个依赖节点,该键的值是依赖节点所依赖的节点列表。

此外,假设 map 有 4 个键(A、B、C 和 D)以及以下依赖项:

Dependencies

我正在寻找一种算法(某种拓扑排序?),它会产生一个字符串 vector ,使得字符串按以下顺序出现:

F, B, C, D, A
0 1 2 3 4

此列表表示应评估依赖项的顺序。

最佳答案

我最近想出了一个基于 this algorithm 的解决方案:

这是对您的数据结构稍作修改的版本:

#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

/**
* Performs dependency resolution using
* a topological sort
*/
template<typename ValueType>
class Resolver
{
public:
using value_type = ValueType;
using value_vec = std::vector<value_type>;
using value_map = std::map<value_type, value_vec>;

private:
value_vec seen;
value_map deps;

void resolve(value_type const& d, value_vec& sorted)
{
seen.push_back(d);
for(auto const& nd: deps[d])
{
if(std::find(sorted.begin(), sorted.end(), nd) != sorted.end())
continue;
else if(std::find(seen.begin(), seen.end(), nd) == seen.end())
resolve(nd, sorted);
else
{
std::cerr << "Circular from " << d << " to " << nd << '\n';
continue;
}
}
sorted.push_back(d);
}

public:

/**
* Clear the resolver ready for new
* set of dependencies.
*/
void clear()
{
seen.clear();
deps.clear();
}

/**
* Items that don't depend on anything
*/
void add(value_type const& a)
{
deps[a];
}

/**
* Item a depends on item b
*/
void add(value_type const& a, value_type const& b)
{
deps[a].push_back(b);
}

value_vec resolve()
{
value_vec sorted;
for(auto const& d: deps)
if(std::find(sorted.begin(), sorted.end(), d.first) == sorted.end())
resolve(d.first, sorted);
return sorted;
}
};

int main()
{
Resolver<std::string> resolver;

resolver.add("A", "B");
resolver.add("A", "C");
resolver.add("A", "D");

resolver.add("B", "F");

resolver.add("C", "B");
resolver.add("C", "F");

resolver.add("D", "C");

resolver.add("F");

for(auto const& d: resolver.resolve())
std::cout << d << '\n';
}

输出:

F
B
C
D
A

如果您发现任何错误(尚未经过很好的测试),请告诉我。

从评论中添加:

For efficiency, in production code, if the node type (string, in this example) can be imbued with a flag to mark the node as seen/sorted, then the calls to std::find can be replaced with setting the seen/sorted values for flag. Of course, in this example, Galik couldn't do that, which is why std::find is used, instead. - @Dess

关于c++ - 如何拓扑排序这个数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32108734/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com