//作者: Gods_巨蚁 //反馈方式 //E-mail:ljsunlin@126.com //QQ:517377100 //Blog:http://hi.baidu.com/zhongji //Permutation.h #include <algorithm> //与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) );//这里只支持仿函数形式,不支持一般函数 }
//作者: Gods_巨蚁 //反馈方式 //E-mail:ljsunlin@126.com //QQ:517377100 //Blog:http://hi.baidu.com/zhongji //main.cpp #include <iostream> #include <vector> #include <list> #include <algorithm> #include "Permutation.h" //模板必须把定义放到头文件里!!! int main() { std::list<int> coll1; for(int i = 1; i <= 3; ++i) coll1.push_back(i); /*do{ std::copy(coll.begin(), coll.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "/n"; }while( std::next_permutation(coll.begin(), coll.end()) );*/ std::cout << "coll1: ant_next_permutation" << std::endl; do{ std::copy(coll1.begin(), coll1.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "/n"; }while( ant_next_permutation(coll1.begin(), coll1.end()) ); std::cout << "coll1: ant_prev_permutation greater<int>" << std::endl; do{ std::copy(coll1.begin(), coll1.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "/n"; }while( ant_prev_permutation(coll1.begin(), coll1.end(), std::greater<int>()) ); //coll2 std::list<int> coll2; for(int i = 3; i >= 1; --i) coll2.push_back(i); std::cout << "coll2:ant_next_permutation greater<int>" << std::endl; do{ std::copy(coll2.begin(), coll2.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "/n"; }while( ant_next_permutation(coll2.begin(), coll2.end(), std::greater<int>()) ); std::cout << "coll2:ant_prev_permutation" << std::endl; do{ std::copy(coll2.begin(), coll2.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "/n"; }while( ant_prev_permutation(coll2.begin(), coll2.end()) ); system("PAUSE"); }