使用STL c++创建传递对集

Making a Transitive Pair Set using STL C++

本文关键字:创建 STL c++ 使用      更新时间:2023-10-16

我想创建一个具有传递对的集合。我的输入形式是pair<int, int>我需要一个集合它包含给定输入的所有传递对。例如,如果我有一对{1,2}{2,1}{2,3}{3,4}作为输入,那么我需要一个包含一对{{1,2},{2,1},{1,3},{3,4},{1,4},{2,4}的SET。我还需要找出一个给定的对是否属于这个传递集合。是否有任何内置的数据结构/STL库允许我在c++中完成此操作?

你有一个图,你想把它变成一个自由类别,也就是那个图的传递闭包。

你的int对元素是顶点,这些对本身是边,这就是你的图。图上的自由范畴是有边合成定律的图,以及所有由该定律产生的附加边。法律规定

  • 如果有一个边(或"箭头"作为范畴理论命名它)fa运行到b
  • 和从bc的边缘g
  • 然后还有另一条边f∘gac
  • 组合是关联的((f∘g)∘h = f∘(g∘h))

(每个类别也有单位边,标记为1 a ,从aa对于每个顶点a,以及一个定律,即对于每个从ab的箭头f, 1 a ∘f = f∘1 b = f,但我们不谈论这些)。

在此完成本回答的通识教育部分。

c++标准库中没有相关的算法,但您可能想要检查boost::graph或任何其他面向图形的库。boost::graphtransitive_closure方法,这正是你想要的。

你可以用:

set<pair<int, int>> myset;

传递闭包可以这样计算:

void transitive_closure(set<pair<int, int>>& s)
{
    set<pair<int, int>> a;   // missing nodes to add
    for (auto i = s.cbegin(); i != s.cend(); i++)
    {
        for (auto j = i; ++j != s.cend(); j)
        {
            if (i->second == j->first 
                  && i->first != j->second 
                  && s.count(make_pair(i->first, j->second))==0 )
                a.insert(make_pair(i->first, j->second));
        }
    }
    if (!a.empty()) {
        for (auto p : a)
            s.insert(p);
        transitive_closure(s);
    }
}

这不是最优化的算法,因为递归会重复一些比较。但它是有效的。顺便说一下,我想你忘记了结果集中的{2,3}。

要检查一对是否属于集合,只需检查s.count(make_pair(i->first, j->second)!=0