仅添加列表中的唯一对

时间:2014-01-01 21:23:51

标签: c++ algorithm

说我有:

listA的。

我认为有一个功能:

bool isValidPair(a,b);

如果该函数对b返回true,则对于b也是如此。

在天真的情况下,我会这样:

for each a in listA
for each b in listA
{
   if(a != b && isValidPair(a,b) && 1istC.contains(a,b))
     {
        listC.add(a,b);
     }
}

然而,这涉及到包含功能,但我想知道是否有一种聪明的方法可以以有效的方式做到这一点。

我实际上正在寻找成对的碰撞轴对齐边界框。然后我将对这些对使用脉冲分辨率。

由于

2 个答案:

答案 0 :(得分:4)

只需使用现有算法即可。如果我已正确理解您的问题,std::set_intersection()可以完成工作:

int main()
{
    //For example: Lists of ints;

    std::vector<int> a = { 1 , 2 , 3 , 5 , 7 , 11 , 13 };
    std::vector<int> b = { 1 , 3 , 5 , 7 , 9 , 11 , 13 };
    std::vector<int> result;

    std::set_intersection( std::begin( a ) , std::end( a ) ,
                           std::begin( b ) , std::end( b ) ,
                           std::back_inserter( result )
                         );
}

执行后result的内容为:

  

1 3 5 7 11 13

答案 1 :(得分:1)

std::set是一个没有重复的容器。

std::set需要operator <定义(或自定义等效仿函数) 您想将{a, b}视为{b, a} 我使用了一个特殊的比较器,将{a,b}视为{min(a, b), max(a, b)} 让配对的比较器完成工作。

以下可能会有所帮助:

template <typename T>
struct unorderLess
{
    bool operator () (const std::pair<T, T>& lhs, const std::pair<T, T>& rhs) const
    {
        const auto lhs_order = lhs.first < lhs.second ? lhs : std::tie(lhs.second, lhs.first);
        const auto rhs_order = rhs.first < rhs.second ? rhs : std::tie(rhs.second, rhs.first);

        return lhs_order < rhs_order;
    }
};

int main(int argc, char *argv[])
{
    std::set<std::pair<int, int>, unorderLess<int>> s;

    s.insert({50, 42});
    s.insert({42, 50});
    s.insert({50, 42});
    s.insert({42, 42});

    assert(s.size() == 2); // {42, 42}, {50, 42}

    return 0;
}