std :: set_intersection基本用法

时间:2014-12-28 00:50:39

标签: c++ c++11 stl stl-algorithm

我练习c ++标准库。这是我使用set_intersection

时遇到的一个问题

我尝试解决项目Euler的问题45:

  

三角形,五边形和六边形数字由以下公式生成:

Triangle      Tn=n(n+1)/2     1, 3, 6, 10, 15, ...
Pentagonal    Pn=n(3n−1)/2    1, 5, 12, 22, 35, ...
Hexagonal     Hn=n(2n−1)      1, 6, 15, 28, 45, ...
     

可以证实T285 = P165 = H143 = 40755。

     

找到下一个三角形和六角形的三角形数字。

这是我的技巧代码:

using bint = unsigned long long;

auto pb045()->bint
{

    for (auto max_nb = 1024;; max_nb = max_nb << 1) {

            auto tris = std::vector<bint>{};
            tris.reserve(max_nb);

            auto pentas = std::vector<bint>{};
            pentas.reserve(max_nb);

            auto hexas = std::vector<bint>{};
            hexas.reserve(max_nb);
            for (auto i = 0; i < max_nb; i++) {
                    tris.push_back(i * (i + 1) / 2);
                    pentas.push_back(i * (3 * i - 1) / 2);
                    hexas.push_back(i * (2 * i - 1));
            }

            auto intersection1 = std::vector<bint>(max_nb);

            std::sort(tris.begin(), tris.end());
            std::sort(hexas.begin(), hexas.end());
            std::sort(pentas.begin(), pentas.end());

            auto 
                    begin = intersection1.begin(),
                    end =
            std::set_intersection(hexas.begin(), hexas.end(),
                                  pentas.begin(), pentas.end(),
                                  intersection1.begin());

            auto intersection = std::vector<bint>(end - begin);

            std::set_intersection(begin, end,
                                  tris.begin(), tris.end(),
                                  intersection.begin());

            if (intersection.size() > 3) {
                    // [0] -> 0
                    // [1] -> 1
                    _ASSERT(intersection[2] == 40755);
                    return intersection[3];
            }
    }

这里:

  • 算法没有给出好的解决方案
  • 如果我评论sort行,它会在调试模式下使用消息sequence not ordered崩溃(在MS VC ++上),并在发布模式下长时间运行(但数字按递增顺序插入,所以sort没用。)

我认为我在这里错过了一些东西。

2 个答案:

答案 0 :(得分:2)

pentasi == 37838i)时,int出现溢出,因此您的数组不再按构造排序。您可能需要bint i

答案 1 :(得分:1)

std::set_intersection假设传递给它的范围是有序的。如果您违反该合同,则不再保证算法的输出有意义。根据您的描述,VC ++库实现可能在调试模式(例如,基于NDEBUG)中检查输入范围是否满足此属性。这就是为什么您需要在致电std::sort之前致电std::set_intersection