如何打印集合中的所有元素?

时间:2020-01-19 16:30:29

标签: c++ set

我无法打印出集合中的元素。

std::set<triple, Compare> edges;
for (int i = 0; i < n; i++)
            for (std::list<std::pair<int, int>>::iterator j = graph[i].begin(); j != graph[i].end(); j++)
                edges.insert(makeTriple((*j).second, i, (*j).first));

        for (std::set<triple, Compare>::iterator j = edges.begin(); j != edges.end(); j++)
            printf("%d and %d\n\n", (*j).first + 1, (*j).second + 1);

仅打印7个元素,共13个。 比较功能如下:

bool operator()(const triple &a, const triple &b) const
    {
        if (a.distance == b.distance && a.first == b.first)
            return (a.second < b.second);
        if (a.distance == b.distance && a.second == b.second)
            return (a.first < b.first);
        return (a.distance < b.distance);
    }

2 个答案:

答案 0 :(得分:1)

打印效果很好:它会向您显示其中的内容。较短的版本可能是:

   for (auto j = edges.begin(); j != edges.end(); j++)
        printf("%d and %d\n\n", j->first + 1, j->second + 1);

甚至:

   for (auto e: edges)
        cout << e.first+1 <<" and "<< e.second+1<<endl<<endl;

问题出在比较器中。在插入时,集合将要插入的元素与集合中已经存在的元素进行比较。如果存在某些“相等”(基于比较器),则不会插入该元素。

您的症状告诉我们您的比较器不符合标准库的 compare requirements ,这是严格的弱排序。

您可以轻松地自己进行测试并比较不同的三元组。如果您选择Compare comp;,则!comp(a,b) && !comp(b,a)的那些被认为是相等的。

采用以下三元组(distance, first, second):对于(1, 2, 3)和b (1,3, 2)。您可以轻松地!comp(a,b)&&!comp(b,a)转向!(1 <1)&&!(1 <1)是正确的,因此set会将它们视为相等,并且最终结果中只有两者之一。

如何更正?

您需要处理距离相等但第一个不同而第二个不同的情况。所以最后,重要的是第一还是第二?

假设它是第一个,您可以编写:

bool operator()(const triple &a, const triple &b) const
{
    if (a.distance == b.distance && a.first == b.first)
        return (a.second < b.second);
    if (a.distance == b.distance)
        return (a.first < b.first);
    return (a.distance < b.distance);
}

或更多compact way

bool operator()(const triple &a, const triple &b) const
{
    return tie(a.distance,a.first, a.second)< tie(b.distance,b.first, b.second);
}

不幸的是,紧凑的方式是C ++ 11,所以如果auto在学校不工作,tie也不会

答案 1 :(得分:1)

您的Compare函数不满足要求

应用于调用类型为Compare的对象的函数调用操作的返回值,根据上下文转换为bool时,如果调用的第一个参数出现在true之前,则返回false这种类型引起的严格弱排序关系中的第二个,否则为bool operator()(const triple &a, const triple &b) const { if (a.distance == b.distance) { if(a.first == b.first) return a.second < b.second; else return a.first < b.first; } else return a.distance < b.distance; }

最明显的解决方法是:

<tuple>

不过,可以使用bool operator()(const triple &a, const triple &b) const { return std::tie(a.distance, a.first, a.second) < std::tie(b.distance, b.first, b.second); } 中的std::tie来简化此操作:

<a href="#" class="close"></a>

Demo