全排列問題

2021-07-30 07:35:33 字數 2599 閱讀 5095

全排列就是從第乙個數字起 每個數分別與它後面的數字交換

用c++寫乙個函式, 如 foo(const char *str), 列印出 str 的全排列, 

如 abc 的全排列: abc, acb, bca, dac, cab, cba。。

第一種方法:

用遞迴(不包含有重複數字或字元出現的情況)

void swap(char *a, char *b)

//k表示當前選取到第幾個數,m表示共有多少數.

void allrange(char *plstr, int k, int m)

else }

}void foo(char *plstr)

void main()

包含重複出現的數字或字元的情況

void swap(char *a, char *b)

//在plstr陣列中[nbegin,nend]中是否有數字與下標為nend的數字相等

bool isswap(char *plstr, int nbegin, int nend)

return true;

}//k表示當前選取到第幾個數,m表示共有多少數.

void allrange(char *plstr, int k, int m)

else

} }}

void foo(char *plstr)

int main()

第二種方法:

非遞迴實現

要考慮全排列的非遞迴實現,先來考慮如何計算字串的下乙個排列。

如"1234"的下乙個排列就是"1243"。只要對字串反覆求出下乙個排列,全排列的也就迎刃而解了。

如何計算字串的下乙個排列了?來考慮"926520"這個字串,

我們從後向前找第一雙相鄰的遞增數字,"20"、"52"都是非遞增的,"26 "

即滿足要求,稱前乙個數字2為替換數,替換數的下標稱為替換點,再從後面

找乙個比替換數大的最小數(這個數必然存在),0、2都不行,5可以,將5和2交

換得到"956220",然後再將替換點後的字串"6220"顛倒即得到"950226"。

對於像"4321"這種已經是最「大」的排列,採用stl中的處理方法(快速排序),

將字串整個顛倒得到最「小」的排列"1234"並返回false。*/

void swap(char *a, char *b)

//反轉區間

void reverse(char *a, char *b)

//是否存在下乙個排列

bool next_permutation(char a)//這是乙個求乙個排序的下乙個排列的函式,可以遍歷全排列,要包含標頭檔案

} reverse(p, pend);//如果沒找到這樣的兩個數,證明排序已經完成,沒有下乙個排列了

return false;

}//比較函式

//qsort 要求提供乙個 比較函式,是為了做到通用性更好一點

//qsort函式構成的示範:

//sample: int cmp( const void *a , const void *b )

////qsort(word, 100, sizeof(word[0]), cmp);

int qsortcmp(const void *pa, const void *pb)

int main()

while (next_permutation(sztextstr));

system("pause");

return 0;

}

最後是乙個整合的例子

輸入乙個字串s和乙個整數n,其中s中的各個字元均不相等,

並且n小於等於s的長度,請輸出由s中字元組成的長度為n的所有的排列。

比如 要輸出12345中任意3個數的組合

void swap(char *a, char *b)

//k表示當前選取到第幾個數,m表示共有多少數.

void allrange(char *plstr, int k, int m)

else }

}//全排列函式 有序的組合

void foo(char *plstr)//n代表幾個數的全排列

//小於字串總字元個數的輸出 無序的排列

void innercombin(const char *arr, int n, int idx, int count, char *buf)

if (arr[idx] == '\0') return;

buf[count] = arr[idx];

innercombin(arr, n, idx + 1, count + 1, buf);//管輸出的語句.輸出:1 2 3 4

innercombin(arr, n, idx + 1, count, buf);//管往下執行的1->2->3->4

}void combination(const char *arr, int n)//組合

void main()

全排列問題

一 全排列問題演算法描述如下 舉例 345的全排列分別為 345 354 435 453 534 543,可見將整組數中的所有的數分別與第乙個數交換,這樣就總是在處理後n 1個數的全排列。又舉例 45的全排列有 45 54 可見將第乙個數分別與後面的數交換後輸出即為45的全排列。所以,對於乙個很長一...

全排列問題

題目描述814 全排列問題 鍵盤輸入n 1 n 10 個字元,輸出輸出其全排序。第一行為字元個數k,第二行為k個字元,不用空格隔開。輸出其每種排列佔一行,各字元間用一空格隔開。樣例輸入 3abc 樣例輸出 a b c a c b b a c b c a c b a c a b includeint ...

全排列問題

time limit 10000 ms memory limit 65536 kib submit statistic discuss problem description 從n個不同元素任取m m n 個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列,當m n時所有的排...