我有一组包含整数的集合,如下所示:
std::vector<std::set<int> > vec = {{2,4},{1,3,8},{7,5}};
上面的集合
的图示| 2 | 4 |
| 1 | 3 | 8 |
| 7 | 5 |
我需要遍历vector的每个set元素,以便vector vector中的每个set元素访问下一行中的每个set元素,依此类推。
例如,第一行向量(即2)中的集合的第一个元素将访问第二行的第一个元素(即1),然后访问第三行的第一个元素(即7)。同样,这些遍历将按以下顺序进行:First vector row and first set element -> Second vector row and first set element -> Third vector row and first set element
First vector row and first set element -> Second vector row and first set element -> Third vector row and second set element
First vector row and first set element -> Second vector row and second set element -> Third vector row and first set element
First vector row and first set element -> Second vector row and second set element -> Third vector row and second set element
First vector row and first set element -> Second vector row and third set element -> Third vector row and first set element
First vector row and first set element -> Second vector row and third set element -> Third vector row and second set element
First vector row and second set element -> Second vector row and first set element -> Third vector row and first set element
First vector row and second set element -> Second vector row and first set element -> Third vector row and second set element
First vector row and second set element -> Second vector row and second set element -> Third vector row and first set element
First vector row and second set element -> Second vector row and second set element -> Third vector row and second set element
First vector row and second set element -> Second vector row and third set element -> Third vector row and first set element
First vector row and second set element -> Second vector row and third set element -> Third vector row and second set element
结果向量应该是列表的向量,其每个元素如下:
std::vector<std::list<int> > list = {{2,1,7},{2,1,5},{2,3,7},{2,3,5},{2,8,7},{2,8,5},{4,1,7},{4,1,5},{4,3,7},{4,3,5},{4,8,7},{4,8,5}};
列表
的结果向量的图示| 2 | 1 | 7 |
| 2 | 1 | 5 |
| 2 | 3 | 7 |
| 2 | 3 | 5 |
| 2 | 8 | 7 |
| 2 | 8 | 5 |
| 4 | 1 | 7 |
| 4 | 1 | 5 |
| 4 | 3 | 7 |
| 4 | 3 | 5 |
| 4 | 8 | 7 |
| 4 | 8 | 5 |
在C ++中实现这一目标的最有效方法是什么?
答案 0 :(得分:0)
让我们将其分解为几个步骤:
// Add the int to a copy of the list
std::list<int> append_copy(std::list<int> l, int i)
{
l.push_back(i);
return l;
}
// append_copy the list for each element in the set
template<typename OutputIterator>
OutputIterator cross_append(const std::set<int>& s, const std::list<int>& l, OutputIterator d_first)
{
return std::transform(s.begin(), s.end(), d_first, [&](int i){ return append_copy(l, i); });
}
std::vector<std::list<int> > cross_apply(const std::vector<std::set<int> > & vec)
{
// start with a single empty list
std::vector<std::list<int> > result{ {} };
// loop over the input to get the sets
for (auto& s : vec)
{
std::vector<std::list<int> > inner;
auto it = std::back_inserter(inner);
// loop over the last run's intermediate, duplicating it
for (auto& l : result)
{
it = cross_append(s, l, it);
}
result = inner;
}
return result;
}
答案 1 :(得分:0)
标准库中没有现成的解决方案来枚举来自多个AFAIK集合的元素组合。
以下是与next_combination
类似的std::next_permutation
函数的实现。
// advance to next combination, return false if already last combination
template <typename SetOfSetsIter, typename CombinationIter>
bool next_combination(
CombinationIter combFirst, SetOfSetsIter dataFirst, SetOfSetsIter dataLast)
{
for(; dataFirst != dataLast; ++dataFirst, ++combFirst)
{
if(++(*combFirst) != dataFirst->end())
return true;
*combFirst = dataFirst->begin();
}
return false;
}
// make combination from first elements of set's sets as a vector
template <typename SetOfSetsIter>
std::vector<typename std::iterator_traits<SetOfSetsIter>::value_type::const_iterator>
first_combination(SetOfSetsIter dataFirst, SetOfSetsIter dataLast)
{
std::vector<typename std::iterator_traits<SetOfSetsIter>::value_type::const_iterator>
combination;
for(; dataFirst != dataLast; ++dataFirst)
combination.push_back(dataFirst->cbegin());
return combination;
}
用法:
typedef std::vector<int> Set;
typedef std::vector<Set> SetOfSets;
const SetOfSets data = {{2, 4}, {1, 3, 8}, {7, 5}};
std::vector<Set::const_iterator> comb = first_combination(data.cbegin(), data.cend());
std::cout << "First to last:" << std::endl;
do
{
for(const auto& it : comb)
std::cout << *it << " ";
std::cout << std::endl;
} while(next_combination(comb.begin(), data.cbegin(), data.cend()));
comb = first_combination(data.cbegin(), data.cend());
std::cout << "\nLast to first:" << std::endl;
do
{
for(const auto& it : comb)
std::cout << *it << " ";
std::cout << std::endl;
} while(next_combination(comb.rbegin(), data.crbegin(), data.crend()));