我正在尝试编写一个tempate函数,它接受一个序列(通过2个迭代器)并计算该序列的排列数,其中没有连续的相同元素。 多数民众赞成在做什么
template<class Iterator>
size_t count_perm(Iterator p, Iterator q)
{
if (p == q)
return 1;
size_t count = 0;
while(std::next_permutation(p, q)){
if(std::adjacent_find(p,q) != q)
++count;
}
}
/*Example
std::array<int, 3> a1 = {1,2,3};
size_t c1 = count_perm(a1.begin(), a1.end()); // 6
std::array<int, 5> a2 = {1,2,3,4,4};
size_t c2 = count_perm(a2.begin(), a2.end()); // 36*/
如果我传递const迭代器,这段代码不起作用。我应该更改什么才能使它与const迭代器一起使用?
答案 0 :(得分:2)
如果我传递const迭代器,这段代码不起作用。我应该更改什么才能使它与const迭代器一起使用?
您不能:std::next_permutation()
修改值,因此与const迭代器不兼容。
- 编辑 -
OP问
如何以正确的方式实现此功能?
我建议你遵循Jarod42的建议:在副本上工作。
我建议如下
template <class Container>
size_t count_perm (Container c) // note: c is a copy
{
if ( c.cbegin() == c.cend() )
return 1;
size_t count = 0U;
std::sort(c.begin(), c.end());
if (std::adjacent_find(c.cbegin(), c.cend()) != c.cend()))
{
std::size_t ui = c.size();
for ( count = ui ; --ui > 1 ; count *= ui )
;
// count now is c.size() ! (factorial of)
}
else
{
while (std::next_permutation(c.begin(), c.end()))
if (std::adjacent_find(c.cbegin(), c.cend()) != c.cend())
++count;
}
return count; // remember this return!
}
答案 1 :(得分:1)
为您修复了模板化函数(仍然需要非常量迭代器):
template<class Iterator> size_t count_perm(Iterator p, Iterator q)
{
if (p == q || std::all_of(p, q, [&](auto &el) {return el == *p; })))
return 0;
size_t count = 1;
std::sort(p, q);
while (std::next_permutation(p, q))
if (std::adjacent_find(p, q) == q)
++count;
return count;
}
std::adjacent_find
会返回end
,因此您应该== q
而不是!= q
你的例子产生6和37.它应该是36而不是37吗?
答案 2 :(得分:0)
解决了这个练习如下,它适用于const迭代器:
template<class Iterator>
size_t count_permutations(Iterator p, Iterator q)
{
using T = typename std::iterator_traits<Iterator>::value_type;
if (p == q)
return 1;
std::vector<T> v(p,q);
std::sort(v.begin(), v.end());
size_t count = 0;
do{
if(std::adjacent_find(v.begin(),v.end()) == v.end()) {
++count;
}
} while(std::next_permutation(v.begin(), v.end()));
return count;
}
问题是使用std::type_traits<Iterator>::value_type
代替Iterator::value_type
(不使用const iters和简单指针(如int *))