STL复习之算法五

1、next_permutation() 。

next_permutation()会取得[first,last)所标示之序列的下一个排列组合。如果没有下一个组合,便返回为false;否则,当前序列被排序成当前序列的下一个序列并且返回为true。

算法实现:

template <class _BidirectionalIter, class _Compare>
bool __next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
                        _Compare __comp) {
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  if (__first == __last)
    return false;
  _BidirectionalIter __i = __first;
  ++__i;
  if (__i == __last) //只有一个元素,只有一个排列,不存在下一个排列,返回为false
    return false;
  __i = __last;
  --__i;             //i指向最后一个元素

  for(;;) {
    _BidirectionalIter __ii = __i; //ii的指向范围为从序列的最后一个元素到顺数第二个元素
    --__i;//i为ii前面一个元素
    if (__comp(*__i, *__ii)) {
      _STLP_VERBOSE_ASSERT(!__comp(*__ii, *__i), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
      _BidirectionalIter __j = __last; 
      while (!__comp(*__i, *--__j)) {}//j从最后一个元素向前迭带,直到 *__i<*__j
      iter_swap(__i, __j);            //交换__i与__j所指向的元素
      reverse(__ii, __last);          //ii之后的元素反转
      return true;                    //返回为true,结束算法
    }
    if (__i == __first) {        //当前序列就是最小序列,不存在下一序列
      reverse(__first, __last);  //序列间的元素全部反转
      return false;              //返回为false,结束算法
    }
  }
#if defined (_STLP_NEED_UNREACHABLE_RETURN)
    return false;
#endif
}

   测试代码:

template<typename T>
void traverseEle(const std::vector<T> array)
{
    for(auto it=array.begin();it!=array.end();++it)
        std::cout<<*it<<"\t";

    std::cout<<std::endl;
}

//测试函数
int main()
{
    std::vector<char> charArray={'a','b','c','d','e'};
    std::cout<<"before next_permutation:\n";
    traverseEle(charArray);

    std::next_permutation(charArray.begin(),charArray.end());
    std::cout<<"before next_permutation:\n";
    traverseEle(charArray);
}

      执行结果:

2、prev_permutation()。取得当前序列的前一序列,若存在,则将当前序列置为当前序列的下一序列;否则,返回为false。

  算法实现:

template <class _BidirectionalIter, class _Compare>
bool __prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
                        _Compare __comp) {
  if (__first == __last)
    return false;
  _BidirectionalIter __i = __first;
  ++__i;
  if (__i == __last)
    return false;
  __i = __last;
  --__i;

  for(;;) {
    _BidirectionalIter __ii = __i;
    --__i;
    if (__comp(*__ii, *__i)) {       //与next_permutation的第一处差别
      _STLP_VERBOSE_ASSERT(!__comp(*__i, *__ii), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
      _BidirectionalIter __j = __last;
      while (!__comp(*--__j, *__i)) {}//与next_permutation的第二处差别
      iter_swap(__i, __j);
      reverse(__ii, __last);
      return true;
    }
    if (__i == __first) {
      reverse(__first, __last);
      return false;
    }
  }
#if defined (_STLP_NEED_UNREACHABLE_RETURN)
    return false;
#endif
}

测试代码:

template<typename T>
void traverseEle(const std::vector<T> array)
{
    for(auto it=array.begin();it!=array.end();++it)
        std::cout<<*it<<"\t";

    std::cout<<std::endl;
}

//测试函数
int main()
{
    std::vector<char> charArray={'a','b','c','d','e'};
    std::cout<<"before next_permutation:\n";
    traverseEle(charArray);

    std::next_permutation(charArray.begin(),charArray.end());
    std::cout<<"after next_permutation:\n";
    traverseEle(charArray);

    std::prev_permutation(charArray.begin(),charArray.end());
    std::cout<<"after prev_permutation:\n";
    traverseEle(charArray);
}

运行结果:

猜你喜欢

转载自blog.csdn.net/weixin_40825228/article/details/81086747