next_permutation算法

template <class BidirectionalIterator>
bool next_permutation(
    BidirectionalIterator first,        // iterator, like the C point
    BidirectionalIterator last
    )
{
    if(first == last) return false;     // no element
 
    BidirectionalIterator i = first;
    if(++i == last) return false;       // only one element
 
    i = last;
    --i;                                // do not use i--, why?
 
    for(;;) {   // no statemnet loop, why do not use line 29 ?
        BidirectionalIterator j = i;    // do not use j=i--; why?
        --i;
        // find the last neighbor pair (i,j) which element i < j
        if(*i < *j) {
            BidirectionalIterator k = last;
            while(!(*i < *--k));     // find last k >= i
            iter_swap(i, k);            // swap i and k
            reverse(j, last);           // reverse [j,last)
            return true;
        }
 
        if(i == first) {
            reverse(first, last);       // current is in descending order
            return false;
        }
    }
}

STL使用“!(*i < *j)”进行判断大小,若相等则继续寻找,这样就会跳过重复的元素,进而跳过重复的全排列(如:1,2,2; 和1,2,2)。有人会认为直接使用“*i>=*j”更清晰,对于int这种进本数据类型而言,这并没问题。然而,对于结构体甚至C++而言,元素是一个用户自定义数据类型,如何判断其大小?再退一步讲,如何进行排序?STL追求健壮、高效和精妙,对于用户自定义数据类型的排序,可以增加函数指针或者仿函数(Functional),只需要给定“a<b”的方法(如less(a,b))即可。如需求“a>b”可以转化成“b<a”;求“a==b”可以转化成“!(a<b) && !(b<a)”;求“a>=b”可以转化成“!(a<b)”。因此,一般自定义比较器只需要给定less()即可(对于C++而言,即重载操作符operator<)。

使用“--i;”而不是“i--;”,简言之,前者是先自减再使用,后者是先使用再自减。在这里虽然对结果也不影响,但是这两种实现方法还是有区别的。对于“i--;”来说,编译器首先会将i的值拷贝到临时变量中,然后对i进行自减,最后将临时变量返回;对于“--i”来说,编译器直接将i的值自减,然后将i的值返回。显然,“--i”只执行了两个指令操作,而“i--”执行了三个指令操作。所以能用“--i”的时候尽量不要使用“i--”。(PS:目前编译器已经十分智能了,对于上面的情况,即便写成“i--”仍然会按照“--i”进行编译,但请记住,不要指望任何版本的编译器都能帮你优化代码!)

来自:https://www.cnblogs.com/eudiwffe/p/6260699.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值