全排列演算法總結

2021-08-08 19:21:58 字數 2029 閱讀 5717

本文同時發布在我的個人部落格:

求 n 位的字串的全排列,先確定第 0 位,然後對後面 n-1 位進行全排列,在對 n-1 為進行全排列時,先確定第 1 位,然後對後面的 n-2 位進行全排列...由此得到遞迴函式和遞迴的結束條件。全排列也就是交換位置,到 n-2 位時,就是將 n-2 和 n-1 交換位置。

例如輸入字串abc,則列印出 a、b、c 所能排列出來的所有字串abcacbbacbcacabcba。具體過程如下:

於是我們根據這種思想寫出第乙個版本的演算法:

void perm(char *list, int i, int n) else 

}}

這樣我們實現基本的全排列的功能,但是這樣我們並不能解決一種情況,即類似於abb去重的問題,abb這種交換後一樣的情況在輸出時會輸出兩個,於是我們需要對我們的演算法進行改進,得到第二版的演算法:

bool isswap(char *list, int begin, int end) 

return true;

} ​void perm(char *list, int i, int n) else    }}

}

我們在進行交換前進行判斷,當第 i 個字元和第 j 個字元交換位置時,判斷範圍是 [i, j) 是否有和 j 重複的數,如果重複我們跳過這種情況。

題目內容:對字串(數字,字母,符號)進行全排列,並統計全排列的種樹

輸入描述:輸入乙個字串

輸出描述:輸出字串的全排列,每種情況佔一行,最後一行輸出全排列的個數

輸入樣例

輸出樣例

123 132 213 231 312 321 6

這題目的坑在於對輸出的全排列需要排序,ac**如下:

#include #include #include #include using namespace std;  

int sum=0;  

string s[105];

string str;

void swap(int a,int b)  

bool isswap(int k, int m) ;  

do  

{  cout《輸出的結果為:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

當把 while(next_permutation(num,num+3)) 中的 3 改為 2 時,輸出就變為了:

1 2 3

2 1 3

由此可以看出,next_permutation(num,num+n) 函式是對陣列 num 中的前 n 個元素進行全排列,同時並改變num陣列的值。

另外,需要強調的是,next_permutation() 在使用前需要對欲排列陣列按公升序排序,否則只能找出該序列之後的全排列數。比如,如果陣列 num 初始化為 2,3,1,那麼輸出就變為了:

2 3 1

3 1 2

3 2 1

next_permutation() 函式功能是輸出所有比當前排列大的排列,順序是從小到大。

prev_permutation() 函式功能是輸出所有比當前排列小的排列,順序是從大到小。

此外,next_permutation(node, node+n, cmp) 可以對結構體 num 按照自定義的排序方式 cmp 進行排序。

經典的24點問題就可以用全排列來暴力解決,北郵複試機考就考到了這個題。

c++stl中全排列函式next_permutation的使用

全排列總結

若給你一堆數,讓你輸出他的全排列,可以有以下方式實現,不過各有優點和缺點 1.深度優先搜尋 included include include includeusing namespace std int n int book 100 int ch 100 int kong 100 void dfs ...

全排列總結

馬上藍橋杯省賽了 菜雞又是去當分母的 把一些基礎的演算法都總結一下,當作複習了 首先最簡單的是用stl中的next permutation和prev permutation了 next permutation start,end 是輸出下乙個排列,所以用之前要對陣列進行從小到大排序 void per...

全排列總結

接觸全排列已經好長時間了,一直沒有抽空總結一下全排列的相關問題,下面來說一下!一般地,從n個不同元素中取出m m n 個元素,按照一定的順序排成一列,叫做從n個元素中取出m個元素的乙個排列 arrangement 特別地,當m n時,這個排列被稱作全排列 permutation 特別,當n m時為全...