如何使用 boost::icl::hull?
How do I use boost::icl::hull?
以下代码无效:
typedef boost::icl::interval_set<unsigned> bi_list_type;
typedef bi_list_type::value_type iv_type;
std::vector<iv_type> y;
iv_type x; // how to initialize this?
for (auto i : y)
{
x = boost::icl::hull(x, i);
}
问题是,x
是默认构造的,因此最终 0 始终是 x 的下界。 boost::icl::hull
有没有更好的使用方法?如果是这样,我怎么能不问这里就知道(文档在这方面没有帮助)?
(std::vector
只是一个例子,区间创建实际上发生在循环内部)。
"a better way to use boost::icl::hull"
这 100% 取决于预期的目标。
"(the doc isn't helpful in this regard)"
医生也不知道你的目标;它只会告诉您可以用来实现目标的操作。
我不知道你的目标,但对我来说它看起来很有效:
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using iv_type = icl::discrete_interval<unsigned int, std::less>;
iv_type h{};
for (auto& i : {
iv_type::open(0, 0),
iv_type::left_open(5, 8),
iv_type::right_open(4, 6),
iv_type::closed(6, 7),
}) {
std::cout << "h: " << h << " adding " << i << "\n";
h = hull(h, i);
}
std::cout << "h: " << h << "\n";
}
版画
h: [) adding ()
h: [) adding (5,8]
h: (5,8] adding [4,6)
h: [4,8] adding [6,7]
h: [4,8]
备选方案
既然你提到了interval_set也许你可以做得更好:
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using set = icl::interval_set<unsigned int>;
using ival = set::value_type;
auto s = set{};
s.add(ival::open(0, 0));
s.add(ival::left_open(5, 8));
s.add(ival::right_open(4, 6));
s.add(ival::closed(6, 7));
std::cout << "hull: " << hull(s) << "\n";
}
打印
hull: [4,8]
我认为由于集合的有序性,这会有所不同。根据 meaning/goal.
,这可能是您想要的,也可能不是您想要的
另一种选择
如果你真的想要顺序的“左折叠”行为,但不能有像 [)
或 [min(), max())
这样的初始化器,那么也许把它写成左折叠:
#include <algorithm>
#include <boost/icl/interval_set.hpp>
#include <iostream>
#include <numeric>
namespace icl = boost::icl;
int main() {
using iv_type = icl::discrete_interval<unsigned int, std::less>;
std::vector v{
iv_type::open(0, 0),
iv_type::left_open(5, 8),
iv_type::right_open(4, 6),
iv_type::closed(6, 7),
};
if (v.size()>0) {
std::cout
<< "h: "
<< std::accumulate(begin(v) + 1, end(v), v.front(),
[](auto a, auto const& b) {
return icl::hull(std::move(a), b);
})
<< "\n";
}
}
我们的简单数据仍然打印
h: [4,8]
以下代码无效:
typedef boost::icl::interval_set<unsigned> bi_list_type;
typedef bi_list_type::value_type iv_type;
std::vector<iv_type> y;
iv_type x; // how to initialize this?
for (auto i : y)
{
x = boost::icl::hull(x, i);
}
问题是,x
是默认构造的,因此最终 0 始终是 x 的下界。 boost::icl::hull
有没有更好的使用方法?如果是这样,我怎么能不问这里就知道(文档在这方面没有帮助)?
(std::vector
只是一个例子,区间创建实际上发生在循环内部)。
"a better way to use boost::icl::hull"
这 100% 取决于预期的目标。
"(the doc isn't helpful in this regard)"
医生也不知道你的目标;它只会告诉您可以用来实现目标的操作。
我不知道你的目标,但对我来说它看起来很有效:
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using iv_type = icl::discrete_interval<unsigned int, std::less>;
iv_type h{};
for (auto& i : {
iv_type::open(0, 0),
iv_type::left_open(5, 8),
iv_type::right_open(4, 6),
iv_type::closed(6, 7),
}) {
std::cout << "h: " << h << " adding " << i << "\n";
h = hull(h, i);
}
std::cout << "h: " << h << "\n";
}
版画
h: [) adding ()
h: [) adding (5,8]
h: (5,8] adding [4,6)
h: [4,8] adding [6,7]
h: [4,8]
备选方案
既然你提到了interval_set也许你可以做得更好:
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using set = icl::interval_set<unsigned int>;
using ival = set::value_type;
auto s = set{};
s.add(ival::open(0, 0));
s.add(ival::left_open(5, 8));
s.add(ival::right_open(4, 6));
s.add(ival::closed(6, 7));
std::cout << "hull: " << hull(s) << "\n";
}
打印
hull: [4,8]
我认为由于集合的有序性,这会有所不同。根据 meaning/goal.
,这可能是您想要的,也可能不是您想要的另一种选择
如果你真的想要顺序的“左折叠”行为,但不能有像 [)
或 [min(), max())
这样的初始化器,那么也许把它写成左折叠:
#include <algorithm>
#include <boost/icl/interval_set.hpp>
#include <iostream>
#include <numeric>
namespace icl = boost::icl;
int main() {
using iv_type = icl::discrete_interval<unsigned int, std::less>;
std::vector v{
iv_type::open(0, 0),
iv_type::left_open(5, 8),
iv_type::right_open(4, 6),
iv_type::closed(6, 7),
};
if (v.size()>0) {
std::cout
<< "h: "
<< std::accumulate(begin(v) + 1, end(v), v.front(),
[](auto a, auto const& b) {
return icl::hull(std::move(a), b);
})
<< "\n";
}
}
我们的简单数据仍然打印
h: [4,8]