这里的解决方案满足“已经在另一个元素中”的要求,而不仅仅是元素的“唯一性”。
对于 [[1, 2, 3, 4], [1, 2, 3], [3], [1,2,3,5]],输出为 [[1, 2, 3, 4] , [1,2,3,5]]。
对于 [[1, 2, 3, 4], [1, 2, 3], [3,4], [1,2,3,5]],输出为 [[1, 2, 3, 4],[1,2,3,5]]。
它的工作原理如下:
- 生成将值映射到其容器的向量的映射
- 对于每个向量,计算每个值的容器的交集。如果结果交集中有多个项目(即不仅是自交集),则删除此类向量。
#include <boost/container/vector.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/unordered_map.hpp>
#include <boost/foreach.hpp>
#include <iterator>
#include <iostream>
#include <ostream>
#include <cstddef>
#include <string>
using namespace boost::assign;
using namespace boost;
using namespace std;
template<typename VecVec,typename OutputIterator>
void delete_included(const VecVec &vv,OutputIterator out)
{
typedef typename range_value<VecVec>::type vec_type;
typedef typename const vec_type *vec_id;
typedef typename range_value<vec_type>::type value_type;
unordered_map<value_type,container::vector<vec_id> > value_in;
container::vector<vec_id> all_vec_indexes;
BOOST_FOREACH(const vec_type &vec,vv)
{
all_vec_indexes.push_back(&vec);
BOOST_FOREACH(const value_type &value,vec)
{
value_in[value].push_back(&vec);
}
}
container::vector<vec_id> included_in;
container::vector<vec_id> intersect;
BOOST_FOREACH(const vec_type &vec,vv)
{
included_in=all_vec_indexes;
BOOST_FOREACH(const value_type &value,vec)
{
intersect.clear();
set_intersection(included_in,value_in[value],back_inserter(intersect));
swap(included_in,intersect);
if(included_in.size()==1)
break;
}
if(included_in.size()==1)
{
*out=vec;
++out;
}
}
}
template<typename VecVec>
void print(const VecVec &vv)
{
typedef typename range_value<VecVec>::type vec_type;
typedef typename range_value<vec_type>::type value_type;
cout << string(16,'_') << endl;
BOOST_FOREACH(const vec_type &vec,vv)
{
copy(vec,ostream_iterator<const value_type&>(cout," "));
cout << endl;
}
}
int main(int argc,char *argv[])
{
container::vector<container::vector<int> > vv
(list_of
( list_of (1)(2)(3)(4) )
( list_of (1)(2)(3) )
( list_of (3) )
( list_of (1)(2)(3)(5) )
);
print(vv);
container::vector<container::vector<int> > result;
delete_included(vv,back_inserter(result));
print(result);
return 0;
}