我练习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
没用。)我认为我在这里错过了一些东西。
答案 0 :(得分:2)
当pentas
(i == 37838
为i
)时,int
出现溢出,因此您的数组不再按构造排序。您可能需要bint i
。
答案 1 :(得分:1)
std::set_intersection
假设传递给它的范围是有序的。如果您违反该合同,则不再保证算法的输出有意义。根据您的描述,VC ++库实现可能在调试模式(例如,基于NDEBUG
)中检查输入范围是否满足此属性。这就是为什么您需要在致电std::sort
之前致电std::set_intersection
。