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

分治法實現全排列

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>
            欧美护士18xxxxhd| 欧美一区二区在线免费播放| 欧美在线看片| 国产欧美综合在线| 久久久久国产精品一区二区| 亚洲一区三区在线观看| 国产日韩av一区二区| 久久另类ts人妖一区二区| 久久黄色网页| 亚洲青涩在线| 午夜一区二区三区在线观看 | 国产精品视频男人的天堂| 亚洲女人小视频在线观看| 亚洲一区二区三区精品视频| 国产欧美日韩精品a在线观看| 久久综合国产精品台湾中文娱乐网| 久久国产精品久久久久久电车| 在线成人性视频| 亚洲欧美日韩精品| 精品999久久久| 亚洲一区视频在线| 夜夜嗨av一区二区三区网页| 亚洲一区二区三区精品动漫| 亚洲激情视频| 欧美在线亚洲在线| 久久岛国电影| 国产精品视频一二三| 一区二区日韩免费看| 欧美资源在线观看| 一区二区久久久久| 欧美电影在线观看| 欧美激情免费在线| 伊人久久综合| 每日更新成人在线视频| 久久综合999| 亚洲乱码精品一二三四区日韩在线| 欧美在线www| 免费成人av在线| 亚洲高清影视| 男女激情视频一区| 亚洲免费av观看| 亚洲欧美资源在线| 黄色成人在线免费| 噜噜噜噜噜久久久久久91 | 欧美日韩精品| 亚洲午夜高清视频| 久久久午夜精品| 亚洲精品一级| 欧美性开放视频| 久久精品av麻豆的观看方式| 久久久蜜臀国产一区二区| 亚洲福利视频一区| 欧美私人网站| 久久亚洲精品伦理| 一区二区三区精品视频| 久久天天躁夜夜躁狠狠躁2022| 亚洲国产视频直播| 国产精品久久网| 欧美国产日产韩国视频| 亚洲欧美三级在线| 亚洲激情电影中文字幕| 亚洲一区激情| 999在线观看精品免费不卡网站| 老鸭窝91久久精品色噜噜导演| 久久中文字幕一区二区三区| 亚洲性图久久| 99人久久精品视频最新地址| 一区二区三区在线免费观看| 欧美日韩精品一区二区天天拍小说 | 欧美区在线播放| 免费观看欧美在线视频的网站| 日韩一区二区精品| 亚洲精品免费电影| 亚洲国产成人在线| 亚洲韩国青草视频| 欧美激情视频在线播放 | 亚洲欧美第一页| 激情六月婷婷综合| 亚洲电影自拍| 99精品热视频只有精品10| 亚洲免费激情| 午夜精品一区二区三区电影天堂| 一片黄亚洲嫩模| 欧美一区深夜视频| 欧美综合国产| 欧美大色视频| 亚洲一区在线播放| 卡一卡二国产精品| 欧美色图一区二区三区| 国产精品久久久久久久7电影| 国产精品入口夜色视频大尺度| 国产日韩1区| 99日韩精品| 久久久久久色| 在线亚洲精品福利网址导航| 久久精品道一区二区三区| 欧美日韩国产高清| 极品日韩av| 欧美一区亚洲| 亚洲韩国一区二区三区| 欧美一区二区三区在| 欧美成人午夜视频| 在线观看免费视频综合| 欧美一区二区视频在线观看2020| 亚洲第一偷拍| 欧美 日韩 国产 一区| 国产精品综合色区在线观看| 夜夜狂射影院欧美极品| 你懂的视频欧美| 久久精品视频播放| 国产真实乱子伦精品视频| 亚洲欧美日韩一区二区| 一区二区电影免费观看| 欧美日韩一区免费| 亚洲永久精品大片| 亚洲天堂男人| 韩日成人av| 欧美激情视频在线播放 | 亚洲人成啪啪网站| 亚洲乱码国产乱码精品精98午夜| 久久综合狠狠| 在线视频日韩| 欧美亚洲三级| 国产欧美丝祙| 亚洲日韩视频| 一区二区三区免费网站| 欧美激情一区二区三区高清视频 | 久久久久欧美精品| 欧美激情第三页| 亚洲欧美日韩综合一区| 欧美伊久线香蕉线新在线| 在线播放精品| 中日韩视频在线观看| 尤物在线精品| 亚洲尤物精选| 夜夜夜久久久| 久久尤物视频| 久久精品国产综合精品| 欧美日韩成人在线| 欧美.www| 一区二区在线不卡| 亚洲男女自偷自拍| 一区二区三区国产盗摄| 久久一区精品| 久久免费高清| 国内成+人亚洲| 午夜精彩视频在线观看不卡 | 亚洲国产高清一区二区三区| 国产一区深夜福利| 香蕉av福利精品导航| 亚洲一二三级电影| 欧美日韩精品免费| 欧美成人中文字幕| 亚洲精选成人| 欧美性一区二区| 正在播放亚洲| 久久精品伊人| 在线成人h网| 欧美午夜精品久久久久免费视| 亚洲免费观看高清完整版在线观看熊| 亚洲黄一区二区三区| 欧美gay视频| 亚洲无玛一区| 欧美成人自拍| 欧美一区二区三区视频在线观看| 国产精品资源在线观看| 欧美在线视频免费| 亚洲免费av网站| 久久亚洲春色中文字幕| 99re6这里只有精品视频在线观看 99re6这里只有精品 | 欧美日韩另类视频| 久久精品国产91精品亚洲| 最近中文字幕mv在线一区二区三区四区 | 蜜臀久久久99精品久久久久久| 亚洲黄色大片| 另类成人小视频在线| 一区二区三区精密机械公司| 国产一区二区你懂的| 欧美视频一区二区三区四区| 久久人人爽人人爽爽久久| 亚洲素人一区二区| 亚洲国产黄色片| 欧美大片91| 欧美高清视频| 麻豆成人在线观看| 久久女同互慰一区二区三区| 午夜精品国产| 欧美在线观看一二区| 欧美诱惑福利视频| 欧美怡红院视频| 久久亚洲精品中文字幕冲田杏梨| 亚洲尤物视频网| 欧美一区二区三区啪啪| 亚洲欧美日韩精品| 久久久久久久一区二区| 久久精品盗摄| 亚洲高清视频的网址| 亚洲区免费影片| 亚洲尤物在线视频观看| 久久精品av麻豆的观看方式|