我想做的事情:
我有一个使用STL的简单集合并函数,我试图将其包装在一个函数中,以便让我执行包含在STL数据结构中的任意多个集合的并集(例如
我的尝试方法: 首先,我的简单集合并:
或者
std::list
、std::vector
、std::forward_list
等)。我的尝试方法: 首先,我的简单集合并:
#include <algorithm>
template <typename set_type>
set_type sunion(const set_type & lhs, const set_type & rhs)
{
set_type result;
std::set_union( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), std::inserter(result, result.end()) );
return result;
}
其中,set_type
定义了一些STL std::set<T>
,例如 std::set<int>
。
在注意到多次需要对集合的迭代器执行多个联合操作后(在Python中,这将是对某个可迭代集合对象上我的sunion
函数的一个reduce
),例如,我可能会有:
std::vector<std::set<int> > all_sets;
或者
std::list<std::set<int> > all_sets;
等等,我需要澄清一下,您是需要将以下的句子翻译成中文吗?
all_sets
是多个集合,我希望得到它们的并集。为此,我正在尝试实现一个简单的reduce函数来完成这项任务(它本质上实现了一个更快、更优雅、非复制的版本)。
sunion(... sunion( sunion( all_sets.begin(), all_sets.begin()+1 ), all_sets.begin()+2 ) , ... )
简单来说,为了快速实现这一点,我只需声明一个set_type result
,然后迭代遍历all_sets
并将每个集合中的值插入到结果对象中:
template <typename set_type>
set_type sunion_over_iterator_range(const std::iterator<std::forward_iterator_tag, set_type> & begin, const std::iterator<std::forward_iterator_tag, set_type> & end)
{
set_type result;
for (std::iterator<std::forward_iterator_tag, set_type> iter = begin; iter != end; iter++)
{
insert_all(result, *iter);
}
return result;
}
其中 insert_all
被定义为:
// |= operator; faster than making a copy and performing union
template <typename set_type>
void insert_all(set_type & lhs, const set_type & rhs)
{
for (typename set_type::iterator iter = rhs.begin(); iter != rhs.end(); iter++)
{
lhs.insert(*iter);
}
}
为什么它不起作用:
不幸的是,我的sunion_over_iterator_range(...)
在使用std::vector<set_type>::begin(), std::vector<set_type>::end()
这些参数时不起作用,因为它们的类型为std::vector<set_type>::iterator
。我认为std::vector<T>::iterator
返回一个iterator<random_access_iterator_tag, T>
。
在编译失败后,由于迭代器类型不兼容,我查看了stl vector源码(位于/usr/include/c++/4.6/bits/stl_vector.h,适用于g++ 4.6和Ubuntu 11.10),惊讶地发现vector<T>::iterator
的typedef被定义为typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
。我曾认为ForwardIterator是RandomAccessIterator的子类型,应该可以正常工作,但显然我是错误的,否则我就不会在这里了。
我会尽力而为的,教练!请帮助我,避免我制造出糟糕的代码,让您的编程智慧不浪费于此...
reduce
等效函数。它被称为std::accumulate。(虽然我不确定它是否在这种情况下有用)。 - Mankarse