C++求數組的全排列之字典序法

kdloeki 9年前發布 | 1K 次閱讀 C/C++

字典序法說明:
字典序列算法是一種非遞歸算法。而它正是STL中Next_permutation的實現算法。
它的整體思想是讓排列成為可遞推的數列,也就是說從前一狀態的排列,可以推出一種新的狀態,直到最終狀態。比如說,最初狀態是12345,最終狀態是54321。
1.最初狀態為12345,從最后面向前面比較,因為5>4,所以從4后面的序列中找出一個比4大,但是比在4后面的序列中最小的數,因為只有5,所有將4和5調換位置,結果為12354.
2.將原來4后面的序列進行倒置,因為現在只有1個4,倒置后還是12354.
3.已12354為基礎,繼續上面的步驟進行操作,下一序列的生成步驟如下:
12354(5>3) -> 12354(4,5序列中最小但是比3大的是4) -> 12453(調換4和3) -> 12435(將5,3倒置)

#include <stdio.h>

include <ctype.h>

include <malloc.h>

static void swapNum(int i, int j, int intArray, int num); static int getSmallestButGreatThanIndex(int intArray, int num, int j, int i); static void invertIntArray(int i, int intArray, int num); static void prtIntArray(int intArray, int num);

int main(int argc,char argv[]){ int num = 0; int intArray = NULL; int i = 0; int j = 0;

//檢查參數,必須是2個
if(argc != 2){
    printf("there must be one parameter!\n");
    goto FINALLY;
}

//檢查參數,參數必須是數字
char* ptr = argv[1];
while(*ptr != '\0'){
    if(isdigit(*(ptr++)) == 0){
        printf("please input a numble!\n");
        goto FINALLY;
    }
}

//將參數轉換成int型
num = atoi(argv[1]);
intArray = (int*)malloc(sizeof(int) * num);
//初始化數組:1,2,3,4,5,6......
for(i=0; i<num; i++){
    intArray[i] = i+1;
}

//打印下原始數組
printIntArray(intArray, num);
//從數組最后面往前比較
for(i=num-1,j=num-2; i>=1 && j>=0; i--,j--){
    //如果右邊數的比左邊數的大
    if(intArray[i] > intArray[j]){
        //將左邊的數與右邊數組中最小但是比左邊的數大的數交換
        swapNum(i, j, intArray, num);
        //將左邊數右邊的數組序列倒置
        invertIntArray(i, intArray, num);
        //將整個數組打印
        printIntArray(intArray, num);
        //繼續從數組的最后面往前面比較
        i = num;
        j = num - 1;
    }
}

FINALLY: if(intArray != NULL){ free(intArray); intArray = NULL; } return 0; }

static void swapNum(int i, int j, int* intArray, int num){ int swapi = getSmallestButGreatThanIndex(intArray, num, j, i); int temp = intArray[j]; intArray[j] = intArray[swapi]; intArray[swapi] = temp; }

static int getSmallestButGreatThanIndex(int* intArray, int num, int j, int i){ int m = 0; int swapi = 0; int smallest = num + 1; for(m = i; m<num; m++){ if(intArray[m] > intArray[j] && intArray[m] < smallest){ swapi = m; smallest = intArray[m]; } } return swapi; }

static void invertIntArray(int i, int* intArray, int num){ int m; int n; int temp; for(m=i, n=num-1; (m-n)<0; m++,n--){ temp = intArray[m]; intArray[m] = intArray[n]; intArray[n] = temp; } }

static void printIntArray(int* intArray, int num){ int i; for(i=0; i<num; i++){ printf("%d ",intArray[i]); } printf("\n"); } </pre>

 本文由用戶 kdloeki 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!