青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

分治法實現全排列

Posted on 2011-04-17 16:28 tianwen 閱讀(509) 評論(0)  編輯 收藏 引用

使用分治法實現一個全排列算法。先來看一下算法實現后的效果:

['a','b','c'].
permutation
["a", "b", "c"],
["a", "c", "b"],
["b", "a", "c"],
["b", "c", "a"],
["c", "b", "a"],
["c", "a", "b"]。
注意最后兩項,我先以為可以用next_permutation實現的,后來發現分治法求出的排序和next_permutation并不一樣。

算法描述

分治法求解問題分為三個步驟:
- 分解:將問題分為若干個子問題。
- 解決:遞歸地求解每個子問題。
- 合并:將每個子問題的解合并成為整個問題的解。

現在我們需要求具有n個元素的數組A的全排列。例如:大小為3的數組A=[a,b,c] (為方便起見,我把引號全都省略了,其實應該是A=['a','b','c']。下同),它的全排列為:
[[a,b,c],
[a,c,b],
[b,a,c],
[b,c,a],
[c,a,b],
[c,b,a]]
這是一個大小為 n!*n 的二維數組。

使用分治算法求解全排列的過程如下
- 分解:將數組分為子數組 A[1..k-1] 和一個元素 A[k]。 (1≤k≤n)
- 解決:遞歸地求解每個子數組 A[1..k-1] 的全排列,直至子數組A[1..k-1]為空時結束遞歸。
- 合并:將上一步的結果—A[1..k-1]的全排列(一個二維數組)與元素A[k]合并,得出A[1..k]的全排列。例如:
[[]] 與 a 合并得到 {a}
{a} 與 b 合并得到 [[a,b], [b,a]]
[[a,b],[b,a]] 與 c 合并得到 [[a,b,c],[a,c,b],[c,a,b],[b,c,a],[c,a,b],[c,b,a]]

看下面的圖示會更直觀一些

1. 分解過程

[a,b,c]
/ \
[a,b] c
/ \
[a] b
/ \
[] a

2. 合并過程

[] a
\ /
{a} b
\ /
[[a,b],[b,a]] c
\ /
[[a,b,c],
[a,c,b],
[c,a,b],
[b,a,c],
[b,c,a],
[c,b,a]]

1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            
#include <cstring>
            #include <iostream>
            using namespace std;
            #define N 4
            char str[10];
            void Perm(char *str, int k, int m);
            void Swap(char &a, char &b);
            int main()
            {
            int n;
            while(scanf("%d", &n) != EOF)
            {
            for(int i=0; i<=n; ++i)
            {
            str[i] = i+'0';
            }
            Perm(str, 1, n);
            }
            return 0;
            }
            void Perm(char *str, int k, int m)
            {
            int i;
            if(k == m)
            {
            for(i=1; i<=m; ++i)
            cout<<str[i]<<" "<<flush;
            cout<<endl;
            return;
            }
            for(i=k; i<=m; ++i)
            {
            Swap(str[k], str[i]);
            Perm(str, k+1, m);
            Swap(str[k], str[i]);
            }
            }
            void Swap(char &a, char &b)
            {
            char tmp = a;
            a = b;
            b = tmp;
            }

以上也是BUCT OJ 1140 分治法求解全排列問題的解答報告

但是對于字符串中存在重復的,比較1123,網上給出了這個源碼:
http://fayaa.com/code/view/13115/

1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            
#include <iostream>
            #include <cstring>
            using namespace std;
            #define N 4
            void Swap(char *pa, char *pb);
            void FullPermutation(char *str, int k, int n);
            int IsAppeared(char *str, char t, int begin, int end);
            char str[N+1] = "ADCD";
            int main()
            {
            FullPermutation(str, 0, N);
            return 0;
            }
            void Swap(char *pa, char *pb)
            {
            if(pa != pb)
            {
            char tmp = *pa;
            *pa = *pb;
            *pb = tmp;
            }
            }
            //判斷字符t在字符串的下標begin到end處是否出現過
            int IsAppeared(char *str, char t, int begin, int end)
            {
            for(int j=begin; j<=end; ++j)
            {
            if(t == str[j])
            return 1;
            }
            return 0;
            }
            /*對字符串進行全排列,注意該函數處理了字符重復的情況,字符重復的情況有兩種:
            1. str[i]本身和后面的str[k]相同
            2. str[k]在k+1到i-1的下標之間已經出現過(用IsAppeared()函數去判斷)
            */
            void FullPermutation(char *str, int k, int n)
            {
            if(k == n)
            {
            cout<<str<<endl;
            return;
            }
            for(int i=k; i<n; ++i)
            {
            if(i!=k && (str[i]==str[k]) || IsAppeared(str,str[i],k+1,i-1)) ////用以處理元素重復的情況
            continue;
            Swap(str+k, str+i);
            FullPermutation(str, k+1, n);
            Swap(str+k, str+i);
            }
            }
» 作者:wentian

posts - 1, comments - 0, trackbacks - 0, articles - 0

Copyright © tianwen

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲免费在线| 欧美r片在线| 美女福利精品视频| 久久久久久91香蕉国产| 欧美中文字幕精品| 久久久久久久久综合| 欧美+亚洲+精品+三区| 老司机67194精品线观看| 男人插女人欧美| 亚洲区国产区| 亚洲国产第一页| 一区二区日本视频| 久久激五月天综合精品| 免费在线亚洲欧美| 欧美日韩国产天堂| 国产一区二区三区久久| 亚洲欧洲一区二区在线观看| 亚洲影院在线| 欧美.www| 亚洲一区在线免费| 麻豆精品一区二区av白丝在线| 午夜精品久久| 欧美激情导航| 国模套图日韩精品一区二区| 亚洲日本中文字幕免费在线不卡| 亚洲午夜免费视频| 蜜臀a∨国产成人精品| 亚洲一区二区三区在线看| 久久久水蜜桃| 国产精品日日摸夜夜添夜夜av| 亚洲欧美一区二区精品久久久 | 亚洲国产精品成人| 一区二区三区久久网| 玖玖综合伊人| 国产精品一二三四区| 亚洲伦理自拍| 卡通动漫国产精品| 亚洲视频axxx| 欧美日韩精品二区| 91久久线看在观草草青青| 欧美亚洲日本国产| 99综合电影在线视频| 欧美国产第一页| 精品51国产黑色丝袜高跟鞋| 亚洲综合视频在线| 亚洲精品乱码久久久久久蜜桃麻豆| 欧美在线免费观看| 国产精品久久久久久久久久尿| 亚洲精品在线观看视频| 牛牛精品成人免费视频| 久久国产乱子精品免费女| 国产精品一区免费观看| 亚洲一区二区视频| 一区二区高清在线| 欧美日韩亚洲成人| 亚洲视频免费观看| 一区二区三区不卡视频在线观看| 欧美福利精品| 亚洲激情综合| 亚洲国产一区二区视频| 欧美国产在线观看| 亚洲免费久久| 一本久久精品一区二区| 国产精品中文字幕欧美| 欧美在线91| 久久精品午夜| 亚洲第一在线视频| 亚洲黑丝在线| 欧美图区在线视频| 小嫩嫩精品导航| 午夜精品www| 狠狠色丁香婷综合久久| 久久在线视频| 欧美va天堂在线| 亚洲色图制服丝袜| 亚洲欧美一区二区精品久久久| 国内外成人在线| 欧美91视频| 欧美三级日本三级少妇99| 久久se精品一区精品二区| 久久久久国产精品麻豆ai换脸| 亚洲欧洲日本专区| a91a精品视频在线观看| 国产亚洲欧洲一区高清在线观看| 久久婷婷久久一区二区三区| 欧美成人国产一区二区| 亚洲视频第一页| 性欧美长视频| 亚洲毛片在线| 亚洲欧美日韩一区在线| 亚洲电影下载| 一本色道久久加勒比88综合| 亚洲综合第一页| 亚洲国产婷婷| 午夜精品网站| 99视频精品在线| 久久av资源网站| 在线视频你懂得一区| 久久国产日韩欧美| 制服丝袜激情欧洲亚洲| 久久精品99国产精品| 99热在这里有精品免费| 久久精品一区| 欧美一区成人| 欧美日韩国产一区二区三区| 久久久久久久久久看片| 国产精品电影网站| 91久久精品国产91性色tv| 国产亚洲欧洲一区高清在线观看| 亚洲清纯自拍| 在线播放日韩| 亚洲欧美成人在线| 日韩亚洲欧美成人一区| 久久精品国产99国产精品| 亚洲午夜未删减在线观看| 欧美成人国产一区二区| 久久免费黄色| 国产欧美一区二区三区国产幕精品 | 日韩亚洲欧美成人| 在线观看欧美日韩| 午夜精品久久久久久| 亚洲视频一二区| 欧美高清在线播放| 欧美激情一区二区三区在线视频 | 欧美精品一区二区三区久久久竹菊| 久久久久久综合| 国产日韩一区二区| 亚洲一级一区| 亚洲欧美在线播放| 国产精品国产a级| 999在线观看精品免费不卡网站| 亚洲国产裸拍裸体视频在线观看乱了中文 | 日韩一二三区视频| 麻豆精品国产91久久久久久| 久久婷婷成人综合色| 国产欧美精品日韩精品| 亚洲一区二区三区在线观看视频 | 亚洲国产成人高清精品| 亚洲国产精品久久久久秋霞影院| 久久久久欧美精品| 亚洲国产日韩欧美| 免费观看一级特黄欧美大片| 欧美国产高清| 亚洲精选久久| 欧美日韩国产在线播放网站| 日韩亚洲精品电影| 午夜精品久久久久影视| 国产乱码精品一区二区三区不卡| 亚洲欧美精品在线观看| 久久全球大尺度高清视频| 1000部国产精品成人观看| 久久在线播放| 亚洲激情中文1区| 亚洲在线视频观看| 国产日韩欧美精品一区| 久久久久久网站| 亚洲黄色免费| 中文av一区二区| 国产午夜精品久久久久久免费视 | 欧美激情一区二区久久久| 亚洲精品一区二区三区福利| 欧美日韩国产区| 亚洲欧美日韩天堂| 免费亚洲电影在线观看| 一区二区三区欧美激情| 国产精品一区久久久久| 噜噜噜噜噜久久久久久91| 99视频精品在线| 久久人人爽人人爽爽久久| 亚洲精品国产精品乱码不99| 国产精品久久一区二区三区| 久久精品视频免费播放| 99riav国产精品| 久久婷婷蜜乳一本欲蜜臀| 一本久道久久综合狠狠爱| 国产日韩一区在线| 欧美大片免费久久精品三p| 亚洲性感美女99在线| 欧美77777| 欧美综合国产精品久久丁香| 99这里只有精品| 曰本成人黄色| 国产欧美一区二区色老头 | 欧美有码在线观看视频| 亚洲国产一区二区视频| 国产精品青草久久| 欧美激情一区二区三区四区| 欧美一区二区三区成人 | 噜噜噜噜噜久久久久久91| 亚洲一区二区三区777| 亚洲电影在线看| 久久久亚洲影院你懂的| 性欧美videos另类喷潮| 夜夜夜精品看看| 一区在线播放| 国产精品综合不卡av| 欧美日韩黄色大片| 欧美国产精品| 久久久无码精品亚洲日韩按摩| 午夜精品婷婷|