//与STL库中的next_permutation相比,增加了设置仿函数功能
//std::less<typename std::iterator_traits<BidirectionalIterator>::value_type>打算使用默认模板参数,结果仅允许在类模板上使用。。。
template<class BidirectionalIterator>
bool ant_next_permutation(
BidirectionalIterator beg,
BidirectionalIterator end
)
{
return ant_next_permutation(beg, end, std::less<typename std::iterator_traits<BidirectionalIterator>::value_type>());
/*
BidirectionalIterator pos1, pos2;
pos1 = end;
do{
--pos1;
if(pos1 == beg) //已经全部是降序排列了,重设为升序排列
{
//std::sort(beg, end); 这里不应该用算法sort,否则该函数用于list容器将会出现编译错误
BidirectionalIterator it1 = beg, it2 = end;
--it2;
for(;it1 != it2;)
{
std::iter_swap(it1, it2);
if(++it1 == it2)break;
--it2;
}
return false;
}
pos2 = pos1;
--pos2;
}while(*pos1 < *pos2); //若后者小于前者,继续执行
//[pos1, end) 当前是一个降序排列
//pos2此时指向前一个数据,小于降序排列中的最大值
//现在要用降序排列中的大于pos2处数值的最小数替换掉pos2处数值
BidirectionalIterator pos3;
pos3 = end;
--pos3;
for(; *pos3 < *pos2; --pos3); //执行后pos3处数值为需要替换数值 2此处原来是*pos3 <= *pos2,应该设为<比较合适
std::iter_swap(pos3, pos2); //互换
//确定了pos2的新值后,pos2后方pos1位置的降序排列需要更新为升序排列
//std::sort(pos1, end); 这里不应该用算法sort,否则该函数用于list容器将会出现编译错误
BidirectionalIterator it1 = pos1, it2 = end;
--it2;
for(;it1 != it2;)
{
std::iter_swap(it1, it2);
if(++it1 == it2)break;
--it2;
}
return true;
*/
}
template<class BidirectionalIterator, class BinaryPredicate>
bool ant_next_permutation(
BidirectionalIterator beg,
BidirectionalIterator end,
BinaryPredicate op// = std::less<typename std::iterator_traits<BidirectionalIterator>::value_type>()//这里无法使用该默认参数
)
{
BidirectionalIterator pos1, pos2;
pos1 = end;
do{
--pos1;
if(pos1 == beg) //已经全部是降序排列了,重设为升序排列
{
//std::sort(beg, end); 这里不应该用算法sort,否则该函数用于list容器将会出现编译错误
BidirectionalIterator it1 = beg, it2 = end;
--it2;
for(;it1 != it2;)
{
std::iter_swap(it1, it2);
if(++it1 == it2)break;
--it2;
}
return false;
}
pos2 = pos1;
--pos2;
}while( op(*pos1, *pos2) ); //若后者小于前者,继续执行
//[pos1, end) 当前是一个降序排列
//pos2此时指向前一个数据,小于降序排列中的最大值
//现在要用降序排列中的大于pos2处数值的最小数替换掉pos2处数值
BidirectionalIterator pos3;
pos3 = end;
--pos3;
for(; op(*pos3, *pos2); --pos3); //执行后pos3处数值为需要替换数值
std::iter_swap(pos3, pos2); //互换
//确定了pos2的新值后,pos2后方pos1位置的降序排列需要更新为升序排列
//std::sort(pos1, end); 这里不应该用算法sort,否则该函数用于list容器将会出现编译错误
BidirectionalIterator it1 = pos1, it2 = end;
--it2;
for(;it1 != it2;)
{
std::iter_swap(it1, it2);
if(++it1 == it2)break;
--it2;
}
return true;
}
template<class BidirectionalIterator>
bool ant_prev_permutation(
BidirectionalIterator beg,
BidirectionalIterator end
)
{
return ant_next_permutation(beg, end, std::greater<typename std::iterator_traits<BidirectionalIterator>::value_type>());
}
template<class BidirectionalIterator, class BinaryPredicate>
bool ant_prev_permutation(
BidirectionalIterator beg,
BidirectionalIterator end,
BinaryPredicate op
)
{
/*//这里支持一般函数
return ant_next_permutation( beg, end, std::not2(std::ptr_fun(op)) ); //先使用一般函数配接器,防止出现op为用户定义的普通函数,而not2出错
//一般函数不能使用not1(op)或者not2(op),所以先用ptr_fun(op)
*/
return ant_next_permutation( beg, end, std::not2(op) );//这里只支持仿函数形式,不支持一般函数
}
原文链接: https://www.cnblogs.com/gods/archive/2010/11/11/3887669.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17222
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!