Converting sets of integers into ranges(将整数集转换为范围)
问题描述
将一组整数转换为一组范围的最惯用的方法是什么?
What's the most idiomatic way to convert a set of integers into a set of ranges?
例如给定集合 {0, 1, 2, 3, 4, 7, 8, 9, 11} 我想得到 { {0,4}, {7,9}, {11,11} }.
E.g. given the set {0, 1, 2, 3, 4, 7, 8, 9, 11} I want to get { {0,4}, {7,9}, {11,11} }.
假设我们正在从 std::set 转换为 std::vector
Let's say we are converting from std::set<int> into std::vector<std::pair<int, int>>.
I treat Ranges as inclusive on both sides, since it's more convenient in my case, but I can work with open-ended ranges too if necessary.
我已经编写了以下函数,但我想重新发明轮子.请告知 STL 中是否存在某些内容或对此进行了增强.
I've written the following function, but I feel like reinventing the wheel. Please tell maybe there's something in STL or boost for this.
typedef std::pair<int, int> Range;
void setToRanges(const std::set<int>& indices, std::vector<Range>& ranges)
{
Range r = std::make_pair(-INT_MAX, -INT_MAX);
BOOST_FOREACH(int i, indices)
{
if (i != r.second + 1)
{
if (r.second >= 0) ranges.push_back(r);
r.first = i;
}
r.second = i;
}
ranges.push_back(r);
}
推荐答案
我认为 STL 或 Boost 中没有任何东西可以做到这一点.
I don't think there's anything in the STL or Boost that does this.
你可以做的一件事是让你的算法更通用一点:
One thing you can do is to make your algorithm a little bit more general:
template<class InputIterator, class OutputIterator>
void setToRanges(InputIterator first, InputIterator last, OutputIterator dest)
{
typedef std::iterator_traits<InputIterator>::value_type item_type;
typedef typename std::pair<item_type, item_type> pair_type;
pair_type r(-std::numeric_limits<item_type>::max(),
-std::numeric_limits<item_type>::max());
for(; first != last; ++first)
{
item_type i = *first;
if (i != r.second + 1)
{
if (r.second >= 0)
*dest = r;
r.first = i;
}
r.second = i;
}
*dest = r;
}
用法:
std::set<int> set;
// insert items
typedef std::pair<int, int> Range;
std::vector<Range> ranges;
setToRanges(set.begin(), set.end(), std::back_inserter(ranges));
您还应该考虑使用术语 interval 而不是 range,因为后者在 STL 用语中的意思是可以通过迭代器或指针访问的任何对象序列"(来源).
You should also consider using the term interval instead of range, because the latter in STL parlance means "any sequence of objects that can be accessed through iterators or pointers" (source).
最后,你应该看看 Boost Interval Arithmetic Library,目前正在审查 Boost 是否包含.
Finally, you should probably take at look at the Boost Interval Arithmetic Library, which is currently under review for Boost inclusion.
这篇关于将整数集转换为范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将整数集转换为范围
基础教程推荐
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- CString 到 char* 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 初始化列表*参数*评估顺序 2021-01-01
