全排列算法

全排列的定義見全排列.
這里我們詳細講一下交換法和字典序法

交換法

舉個簡單的例子,假設(shè)我們要對1234進行全排列
1.首先保證1不變,對234進行全排列
同樣的,對234進行全排列可以保證2不變,對34進行全排列,然后保證3不變,對4進行全排列,因為4只有一個數(shù),所以全排列只有一種,然后我們就得到了

1234
1243
1324
1342
1423
1243

2.這樣我們就得到了以1開頭的所有全排列,接下來就是得到分別以2,3,4開頭的全排列了
只要我們將1與2,3,4分別交換,就分別得到了以2,3,4開頭的初始序列。

代碼

#include<iostream>
using namespace std;
int arr[5]={0,1,2,3,4};
void swap(int x,int y)//用于交換數(shù)組的兩個數(shù)
{
    int temp=arr[x];
    arr[x]=arr[y];
    arr[y]=temp;
}
int resove(int n)//遞歸函數(shù)
{
        if(n==5)//當嘗試對不存在的數(shù)組元素進行遞歸時,標明所有數(shù)已經(jīng)排列完成,輸出。
        {
            for(int i=0;i<5;i++)
            cout<<arr[i]; 
            cout<<endl;
            return 0;
        }
        for(int i=n;i<5;i++)//循環(huán)實現(xiàn)交換和之后的全排列  
        {//i是從n開始 i=n;swap(n,i)相當于固定當前位置,在進行下一位的排列。
            swap(n,i);
            resove(n+1);
            swap(n,i); 
        }
         
}
int main()
{
    resove(0);
}

如果初始序列中有重復(fù)元素的話,只要去重就可以了


bool isSwap(int begin,int end)
{
for(int i=begin;i<end;i++)
{
if(arr[i]==arr[end])
return false;
return true;
}
}
然后在循環(huán)的時候加上這個條件就行了。
for(int i=n;i<5;i++)//循環(huán)實現(xiàn)交換和之后的全排列  
        {//i是從n開始 i=n;swap(n,i)相當于固定當前位置,在進行下一位的排列。
               if(isSwap(n,i))
          {
            swap(n,i);
            resove(n+1);
            swap(n,i); 
           }
        }
123的全排列
123
132
213
231
321
312

可能你已經(jīng)發(fā)現(xiàn)了,這樣的輸出是沒有順序的,如果我們要求輸出必須按照字典序輸出的話,這樣顯然是不可以的。所以接下來介紹一種字典序法。

字典序法

直接看代碼吧,我也不知道咋解釋

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
 
const int maxn = 7;
 
char site[maxn] = {0};
string str;
 
void solve(int num)
{
    if(num == str.length())
    {
        for(int i = 0; i < str.length(); ++i)
        {
            cout << site[i];
        }
        cout << endl;
    }
    else
    {
        int flag = 0;       // 判斷是否出現(xiàn)過
        char tmp;
        for(int i = 0; i < str.length(); ++i)
        {
            // 判斷是否出現(xiàn)過
            tmp = str[i];
            flag = 0;
            for(int j = 0; j < num; ++j)
            {
                if(site[j] == tmp)
                {
                    flag = 1;
                    break;
                }
            }
            if(flag == 1) continue;
            site[num] = str[i];
            solve(num+1);
        }
    }
}
 
int main()
{
     
    int count = 0;
    while(cin >> str)
    {
        sort(str.begin(), str.end());       // 按字典序輸出
        solve(0);
        cout << endl;
    }
 
    return 0;
}

注意,字典序法要求輸入的也是一個有序列。
今天在推薦一首歌,過客, 挺好聽的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、全排列的概念 排列: ??從n個數(shù)中選取m(m<=n)個數(shù)按照一定的順序進行排成一個列,叫作從n個元素中取m個...
    楠子小先生閱讀 35,897評論 0 10
  • 問題描述: 對于一個給定的序列 a = [a1, a2, a3, … , an],請設(shè)計一個算法,用于輸出這個序列...
    雨幻逐光閱讀 5,653評論 0 1
  • 題目:給定元素a,b,a,b,c,c,d,求解出所有的排列。思路:首先這道題的算法是一個比較經(jīng)典的算法,它并不是使...
    IT孤獨者閱讀 1,407評論 0 0
  • 問題 給定一個遞增序列其中,,若,則。求它的遞增全排列集合。 所謂遞增全排列是這樣一個有序集合:其中是序列的一個全...
    Azur_wxj閱讀 1,168評論 0 0
  • 問題: 輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串a(chǎn)bc,則打印出由字符a,b,...
    光影墨辰閱讀 453評論 0 2

友情鏈接更多精彩內(nèi)容