亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)

 更新時(shí)間:2013年05月24日 15:48:10   作者:  
本篇文章是對(duì)全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
(一)非遞歸全排列算法
基本思想是:
    1.找到所有排列中最小的一個(gè)排列P.
    2.找到剛剛好比P大比其它都小的排列Q,
    3.循環(huán)執(zhí)行第二步,直到找到一個(gè)最大的排列,算法結(jié)束.
下面用數(shù)學(xué)的方法描述:
給定已知序列 P =  A1A2A3An ( Ai!=Aj , (1<=i<=n  , 1<=j<=n, i != j  ) )
找到P的一個(gè)最小排列Pmin = P1P2P3Pn  有  Pi > P(i-1) (1 < i <= n)
從Pmin開始,總是目前得到的最大的排列為輸入,得到下一個(gè)排列.
方法為:
1.從低位到高位(從后向前),找出“不符合趨勢(shì)”的數(shù)字。即找到一個(gè)Pi,使Pi < P(i+1)。
  若找不到這樣的pi,說明我們已經(jīng)找到最后一個(gè)全排列,可以返回了。
2.在 P(i+1)P(i+2)Pn 中,找到一個(gè)Pj,便得 Pj"剛剛好大于"Pi.
  ("剛剛好大于"的意思是:在 P(i+1)P(i+2)Pn 中所有大于Pi的元素構(gòu)成的集合中最小的元素.)
3.交換 Pi , Pj 的位置.注意:此處不改變i和j的值,改變的是Pi和Pj.
4.交換后, P1P2P3Pn  并不是準(zhǔn)確的后一個(gè)排列。因?yàn)楦鶕?jù)第1步的查找,我們有P(i+1) > P(i+2) > . > Pn
  即使進(jìn)行了Pi和Pj的交換,這仍然是這一部分最大的一個(gè)排列。將此排列逆序倒置(變成最小的排列)即為所求的下一個(gè)排列.
5.重復(fù)步驟1-4,直到步驟1中找不到“不符合趨勢(shì)”的數(shù)字.
復(fù)制代碼 代碼如下:

//交換數(shù)組a中下標(biāo)為i和j的兩個(gè)元素的值
void swap(int* a,int i,int j)
{
    a[i]^=a[j];
    a[j]^=a[i];
    a[i]^=a[j];
}

//將數(shù)組a中的下標(biāo)i到下標(biāo)j之間的所有元素逆序倒置
void reverse(int a[],int i,int j)
{
    for(;i<j;++i,--j)
    {
         swap(a,i,j);
    }
}

void print(int a[],int length)
{
    for(int i=0;i<length;++i)
         cout<<a[i]<<" ";
    cout<<endl;
}

//求取全排列,打印結(jié)果
void combination(int a[],int length)
{
    if(length<2) return;

    bool end=false;
    while(true)
    {
         print(a,length);

         int i,j;
         //找到不符合趨勢(shì)的元素的下標(biāo)i
         for(i=length-2;i>=0;--i)
         {
             if(a[i]<a[i+1]) break;
             else if(i==0) return;
         }

         for(j=length-1;j>i;--j)
         {
             if(a[j]>a[i]) break;
         }

         swap(a,i,j);
         reverse(a,i+1,length-1);
    }
}

(二)遞歸算法
令E= {e1 , ..., en }表示n 個(gè)元素的集合,我們的目標(biāo)是生成該集合的所有排列方式。令Ei 為E中移去元素i 以后所獲得的集合,perm (X) 表示集合X 中元素的排列方式,ei . p e r m(X)表示在perm (X) 中的每個(gè)排列方式的前面均加上ei 以后所得到的排列方式。例如,如果E= {a, b, c},那么E1= {b, c},perm (E1 ) = ( b c, c b),e1 .perm (E1) = (a b c, a c b)。對(duì)于遞歸的基本部分,采用n = 1。當(dāng)只有一個(gè)元素時(shí),只可能產(chǎn)生一種排列方式,所以perm (E) = ( e),其中e 是E 中的唯一元素。當(dāng)n > 1時(shí),perm (E) = e1 .perm (E1 ) +e2 .p e r m(E2 ) +e3.perm (E3) + ⋯ +en .perm (En )。這種遞歸定義形式是采用n 個(gè)perm (X) 來定義perm (E), 其中每個(gè)X 包含n- 1個(gè)元素。至此,一個(gè)完整的遞歸定義所需要的基本部分和遞歸部分都已完成。
當(dāng)n= 3并且E=(a, b, c)時(shí),按照前面的遞歸定義可得perm (E) =a.perm ( {b, c} ) +b.perm ( {a,c} ) +c.perm ( {a, b} )。同樣,按照遞歸定義有perm ( {b, c} ) =b.perm ( {c} ) +c.perm ( ), 所以a.perm ( {b, c} ) = ab.perm ( {c} ) + ac.perm ( ) = a b . c + ac.b = (a b c, a c b)。同理可得b.perm ( {a, c}) = ba.perm ( {c}) + bc.perm ( {a}) = b a . c + b c . a = (b a c, b c a),c.perm ( {a, b}) =ca.perm ( ) + cb.perm ( {a}) = c a . b + c b . a = (c a b, c b a)。所以perm (E) = (a b c, a c b, b a c, b c a,c a b, c b a)。注意a.perm ( {b, c} )實(shí)際上包含兩個(gè)排列方式:abc 和a c b,a 是它們的前綴,perm ( {b, c} )是它們的后綴。同樣地,ac.perm ( ) 表示前綴為a c、后綴為perm ( ) 的排列方式。程序1 - 1 0把上述perm (E) 的遞歸定義轉(zhuǎn)變成一個(gè)C++ 函數(shù),這段代碼輸出所有前綴為l i s t [ 0:k-1], 后綴為l i s t [ k:m] 的排列方式。調(diào)用Perm(list, 0, n-1) 將得到list[0: n-1] 的所有n! 個(gè)排列方式,在該調(diào)用中,k=0, m= n - 1,因此排列方式的前綴為空,后綴為list[0: n-1] 產(chǎn)生的所有排列方式。當(dāng)k =m 時(shí),僅有一個(gè)后綴l i s t [ m ],因此list[0: m] 即是所要產(chǎn)生的輸出。當(dāng)k<m時(shí),先用list[k] 與l i s t [ k:m] 中的每個(gè)元素進(jìn)行交換,然后產(chǎn)生list[k+1: m] 的所有排列方式,并用它作為list[0: k] 的后綴。S w a p是一個(gè)inline 函數(shù),它被用來交換兩個(gè)變量的值
復(fù)制代碼 代碼如下:

template <class T>
inline void Swap(T& a, T& b)
{
    // 交換a和b
    T temp = a; a = b; b = temp;
}

template<class T>
void Perm(T list[], int k, int m)
{
    //生成list [k:m ]的所有排列方式
    int i;
    if (k == m)
    {
         //輸出一個(gè)排列方式
         for (i = 0; i <= m; i++)
             cout << list [i];
         cout << endl;
    }
    else // list[k:m ]有多個(gè)排列方式
    {
         // 遞歸地產(chǎn)生這些排列方式
         for (i=k; i <= m; i++)
         {
             Swap (list[k], list[i]);
             Perm (list, k+1, m);
             Swap (list [k], list [i]);
         }
    }
}

相關(guān)文章

  • C++11實(shí)現(xiàn)簡(jiǎn)易定時(shí)器的示例代碼

    C++11實(shí)現(xiàn)簡(jiǎn)易定時(shí)器的示例代碼

    這篇文章主要介紹了C++11實(shí)現(xiàn)簡(jiǎn)易定時(shí)器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • c++動(dòng)態(tài)內(nèi)存管理詳解(new/delete)

    c++動(dòng)態(tài)內(nèi)存管理詳解(new/delete)

    作為一名編程初學(xué)者,通常學(xué)習(xí)中,發(fā)生內(nèi)存錯(cuò)誤是件非常麻煩的事情,下面這篇文章主要給大家介紹了關(guān)于c++動(dòng)態(tài)內(nèi)存管理new/delete的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫清理

    Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫清理

    項(xiàng)目如果需要存儲(chǔ)很多日志記錄比如運(yùn)行日志,時(shí)間長(zhǎng)了記錄數(shù)量非常多,數(shù)據(jù)庫體積不斷增大,對(duì)應(yīng)數(shù)據(jù)庫表的增刪改查的效率不斷降低,因此需要將早期的數(shù)據(jù)清理。本文將詳細(xì)介紹一下通用數(shù)據(jù)庫清理的實(shí)現(xiàn),需要的可以參考一下
    2022-02-02
  • C++實(shí)現(xiàn)屏幕截圖

    C++實(shí)現(xiàn)屏幕截圖

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)屏幕截圖功能,截圖自動(dòng)保存為png格式文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • C++ float、double判斷是否等于0問題

    C++ float、double判斷是否等于0問題

    這篇文章主要介紹了C++ float、double判斷是否等于0問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • C語言實(shí)現(xiàn)計(jì)算圓周長(zhǎng)以及面積

    C語言實(shí)現(xiàn)計(jì)算圓周長(zhǎng)以及面積

    這篇文章主要介紹了C語言實(shí)現(xiàn)計(jì)算圓周長(zhǎng)以及面積方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)

    C語言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 利用C語言實(shí)現(xiàn)猜數(shù)字小游戲

    利用C語言實(shí)現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了利用C語言實(shí)現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 基于C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng)

    基于C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了基于C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 一起來看看C語言的預(yù)處理注意點(diǎn)

    一起來看看C語言的預(yù)處理注意點(diǎn)

    這篇文章主要為大家詳細(xì)介紹了C語言的預(yù)處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論