下一个字典序列(next permutation)

来源:互联网 发布:mastercam线割编程 编辑:程序博客网 时间:2024/05/21 10:51
给定一个序列求这个序列的安字典序排序的下一个序列,最大序列的下一个序列为最小序列,比如:
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

分析:
我们可以从右往左遍历数组,找到从右开始第一个不按照升序排序的数字,记为x,然后再次从右往左遍历一次找到第一个比x大的数字,记为y,然后对调x和y,最后将y之后的数字全部翻转。

举例:
6,7,8,4,3,2
从右找到第一个非升序的数字7
从右找到第一个比7大的数字8
调换7和8,得到6,8,7,4,3,2
将8之后的数字全部翻转得到6,8,2,3,4,7此即为下一个字典序的序列。

代码如下:

 

//c版本

void reverseArray(int a[],int n){

    int mid = n/2-1;

    for(int i = 0;i<=mid;i++){

       int temp = a[i];

       a[i] = a[n-1-i];

       a[n-1-i] = temp;

    }

}

 

void nextPermutation2(int a[],int n){

    int i = n-2;

    while(a[i]>a[i+1]&&i >= 0)

           i--;

    if(i == -1){

       reverseArray(a,n);

       return;

    }

    int j = n-1;

    for(;j>i;j--)

       if(a[j] > a[i])

           break;

    int temp = a[i];

    a[i] = a[j];

    a[j] = temp;

    reverseArray(a+i+1,n-i-1);

}

 

  

//c++版本

void nextPermutation(vector<int>& sequence){

    auto rfirst = reverse_iterator<vector<int>::iterator>(sequence.end());

    auto rend = reverse_iterator<vector<int>::iterator>(sequence.begin());

    auto povite = next(rfirst);

    while((*povite> *prev(povite)) && (povite != rend))

       povite = next(povite);

    if(povite == rend){

       reverse(rfirst,rend);

       return ;

    }

    auto change = find_if(rfirst,rend,bind1st(less<int>(),*povite));

    swap(*povite,*change);

    reverse(rfirst,povite);

    return ;

}


c++版本中涉及到的语法和函数参考:
  • auto变量为自动变量,在c语言中其实大多普通声明方式声明的变量都是auto变量,他们不需要明确指定auto关键字,默认就是auto的了。auto变量在离开作用域是会变程序自动释放,不会发生内存溢出情况(除了包含指针的类)。使用auto变量的优势是不需要考虑去变量是否被释放,比较安全。c++对其做了扩充,除了具有原有的含义外,还增加了一种类似其他高级语言的型别推导特性。使用auto来代替变量的类型,前提是被明确类型的初始化变量初始化的,可以使用auto关键字比如int i=10; auto a = i; //这样a也是int类型了这在使用一些模板类的时候,对于减少冗赘的代码也很有用。
  • reverse_iterator函数,用来对iterator进行反转,将end变为begin,begin变为end
  • find_if函数,此函数的第一二个参数是迭代器的开始和结束,用来表示一串对象的开始和结束,第三个参数是个条件,当找到满足此条件的对象时就返回对象的迭代器(iterator)。
  • bind1st函数,有两个参数(const Operation& op, const T& x)。  bind1st(const Operation& op, const T& x)就是这么一个操作:x op value,对于例子中来说就是*povite 小于 当前迭代器对应的数,所有例子中的find_if功能为找到第一个对象,使得此对象大于*povite,并返回这个对象的迭代器。
  • less是一个仿函数,用来表示小于,他有两个参数,如果第一个参数小于第二个参数则返回true,否则返回false。
0 0
原创粉丝点击