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

分治法實現全排列

Posted on 2011-04-17 16:28 tianwen 閱讀(514) 評論(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

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


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>
            欧美日韩在线一区| 国产精品永久免费视频| 亚洲高清在线视频| 久久综合狠狠综合久久激情| 午夜久久tv| 亚洲国产高清视频| 亚洲欧洲另类国产综合| 欧美精品一区二区视频| 在线中文字幕一区| 亚洲在线视频| 永久免费精品影视网站| 亚洲三级毛片| 国产视频在线观看一区| 模特精品裸拍一区| 欧美三级乱码| 久久九九99视频| 欧美精品国产精品| 欧美在线免费播放| 欧美gay视频激情| 欧美亚洲一区三区| 久久综合一区二区三区| 亚洲视频成人| 久久久久久久成人| 亚洲一区二区三区精品视频| 久久不射2019中文字幕| 亚洲美女精品成人在线视频| 午夜精品福利在线观看| 亚洲国产综合在线看不卡| 亚洲一区二区三区四区五区黄| 激情91久久| 亚洲视频综合| 日韩一本二本av| 久久精品女人| 篠田优中文在线播放第一区| 欧美福利视频在线| 久久综合给合久久狠狠狠97色69| 欧美日韩一区二区在线观看| 美日韩丰满少妇在线观看| 国产精品视频| 一本久道久久综合婷婷鲸鱼| 精品成人在线| 午夜欧美不卡精品aaaaa| 艳女tv在线观看国产一区| 久久久久久久网| 欧美在线1区| 国产精品久久久久久久久久久久久久 | 美女免费视频一区| 国产精品久久久久久av福利软件 | 欧美一级大片在线免费观看| 亚洲卡通欧美制服中文| 久久精品免费| 久久久国产成人精品| 国产精品婷婷| 在线视频你懂得一区二区三区| 亚洲欧洲中文日韩久久av乱码| 久久精品视频免费观看| 久久国产婷婷国产香蕉| 国产精品99一区| 一个色综合导航| 亚洲一区二区三区精品动漫| 欧美日韩国产成人在线| 亚洲人成绝费网站色www| 亚洲人成亚洲人成在线观看| 美女999久久久精品视频| 久久尤物视频| 亚洲高清在线视频| 蜜臀91精品一区二区三区| 欧美成人在线免费观看| 最新国产乱人伦偷精品免费网站| 久久婷婷久久| 亚洲国产99| 亚洲视频精选在线| 欧美性大战久久久久| 亚洲一区二区视频在线观看| 亚洲欧美99| 国产视频一区欧美| 久久久噜噜噜久久| 欧美激情精品久久久| 99re这里只有精品6| 国产精品国产三级国产aⅴ浪潮| 一道本一区二区| 久久久www成人免费精品| 加勒比av一区二区| 欧美国产成人在线| 一本色道精品久久一区二区三区 | 伊人婷婷久久| 欧美电影免费观看高清| 亚洲美女av黄| 久久精品视频va| 亚洲精品一区久久久久久| 欧美日韩亚洲一区二| 亚洲欧美日本国产有色| 久久综合网络一区二区| 亚洲精品久久久久久下一站| 国产精品都在这里| 久久婷婷av| 一区二区免费在线播放| 久久中文在线| 亚洲在线免费观看| 在线看日韩欧美| 国产精品卡一卡二| 蜜桃av一区二区三区| 亚洲视频久久| 亚洲第一天堂av| 久久九九热re6这里有精品| 最近中文字幕日韩精品| 国产欧美欧美| 欧美日韩www| 久久露脸国产精品| 亚洲视频一区| 欧美国产日本高清在线| 午夜在线一区二区| 亚洲最黄网站| 在线精品视频在线观看高清| 国产精品美女诱惑| 欧美精品在线视频| 美女91精品| 欧美在线观看一二区| 中日韩美女免费视频网址在线观看| 免费观看一区| 久久人人爽爽爽人久久久| 亚洲欧美区自拍先锋| 日韩午夜激情电影| 一区二区亚洲精品国产| 国产精品亚洲精品| 欧美午夜一区二区福利视频| 免费观看在线综合| 久久一区国产| 久久狠狠婷婷| 亚洲欧美日韩在线不卡| 夜夜嗨av一区二区三区中文字幕 | 国产精品久久一区二区三区| 欧美韩国一区| 女仆av观看一区| 免费久久99精品国产自在现线| 欧美一区二区在线视频| 午夜精品久久| 欧美尤物一区| 欧美一级视频免费在线观看| 亚洲一区精品视频| 亚洲永久字幕| 欧美在线观看视频一区二区| 亚洲永久在线| 午夜精品久久久久久久白皮肤| 亚洲手机在线| 亚洲免费视频成人| 午夜视频一区在线观看| 亚洲欧美日韩电影| 欧美一区二区高清| 久久精品官网| 久久综合激情| 欧美国产精品va在线观看| 欧美大片18| 欧美视频一区在线观看| 国产精品久久久一本精品| 国产精品系列在线| 韩国一区二区三区在线观看 | 国产亚洲精品aa午夜观看| 国产欧美日韩| 亚洲国产精品嫩草影院| 亚洲精选中文字幕| 亚洲一区亚洲| 久久久久久久网站| 欧美激情精品久久久久久| 亚洲欧洲日韩综合二区| 夜夜爽99久久国产综合精品女不卡| 中文国产亚洲喷潮| 久久狠狠亚洲综合| 欧美激情一区二区久久久| 欧美午夜精品理论片a级按摩| 国产欧美精品久久| 亚洲国产成人在线| 亚洲一区免费网站| 开心色5月久久精品| 亚洲精品中文字幕女同| 亚洲欧美大片| 欧美护士18xxxxhd| 国产一区日韩欧美| 夜夜爽夜夜爽精品视频| 久久精品国产清高在天天线| 亚洲国产精品久久久久| 亚洲欧美国产77777| 免费试看一区| 国产欧美欧洲在线观看| 亚洲精品少妇30p| 久久久91精品国产一区二区三区| 欧美激情亚洲综合一区| 亚洲欧美日韩精品久久亚洲区| 久久综合福利| 国产欧美日韩精品丝袜高跟鞋| 亚洲欧洲一区二区在线观看| 性欧美在线看片a免费观看| 亚洲国产美女精品久久久久∴| 午夜精品亚洲一区二区三区嫩草| 欧美国产成人在线| 在线日韩电影| 久久狠狠一本精品综合网| 99视频在线观看一区三区| 鲁大师影院一区二区三区| 国产婷婷一区二区|