next_permutation() 全排列函數

    排列(Arrangement),簡單講是從 NN 個不同元素中取出 MM 個,按照一定順序排成一列,通常用A(M,N)A(M,N)表示。當M=NM=N時,稱爲全排列(Permutation)。
    從數學角度講,全排列的個數A(N,N)=(N)(N1)...21=N!A(N,N)=(N)*(N-1)*...*2*1=N!,但從編程角度,如何獲取所有排列?那麼就必須按照某種順序逐個獲得下一個排列,通常按照升序順序(字典序)獲得下一個排列。

    例如對於一個集合A=A={1,2,31,2,3},首先獲取全排列a1:1,2,3a1: 1,2,3;然後獲取下一個排列a2:1,3,2a2: 1,3,2;按此順序,AA 的全排列如下:

a1:1,2,3a1: 1,2,3 ;  a2:1,3,2;a2: 1,3,2;   a3:2,1,3a3: 2,1,3 ;  a4:2,3,1a4: 2,3,1 ;  a5:3,1,2a5: 3,1,2 ;  a6:3,2,1a6: 3,2,1 ;  共 66 種。

    那麼我們有時就需要求下一種全排列,在STL中的algorithm已經給出了一種健壯、高效的方法,即 next_permutation(int *begin, int *end)
    注意,這個函數是直接將傳遞的數組轉換成了下一個全排列數組,並且有一個返回值。
    當返回爲 11 時,表示找到了下一全排列;返回 00 時,表示無下一全排列。注意,如果從begin到end爲降序,則表明全排列結束,逆置使其還原到升序

    因而我們可以用這個返回值求得所有的全排列

同時,相對應的,上一個排列即爲prev_permutation(int *begin, int *end)

#include<bits/stdc++.h>
using namespace std;

int main() {
	char a[3]= {'a','b','c'}; //第一個排列保證正序,有時候根據題目要求,需要對其進行排序處理。
	for(int i=1; i<=6; i++) { //i爲總共排列的個數  ,及 3!
		for(int j=0; j<3; j++)
			printf("%c ", a[j]);
		printf("\n");
		next_permutation(a, a+3);//放在第一個排列的後邊,輸出第一個排列的下一個排列
	}
	printf("*******************\n");
	
	int b[4]= {0,1,2,3};
	do{
        for(int i=0; i<4; printf("%d ", b[i++]));
        printf("\n");
    } while(next_permutation(b, b+4));
    printf("*******************\n");
    
    int c[3]={3,2,1};
	next_permutation(c, c+3);
	for(int i=0; i<3; printf("%d ", c[i++]));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章