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

分治法實現全排列

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>
            欧美先锋影音| 在线中文字幕一区| 99xxxx成人网| 亚洲另类一区二区| 国产视频一区在线| 亚洲一区二区三区国产| 亚洲老司机av| 夜夜嗨网站十八久久| 夜夜爽99久久国产综合精品女不卡 | 欧美激情片在线观看| 欧美国产日韩一二三区| 亚洲国产另类 国产精品国产免费| 久久国产黑丝| 欧美国产第二页| av成人老司机| 久久成人这里只有精品| 男人的天堂成人在线| 一区二区三区精密机械公司| 欧美日韩中文| 国产亚洲a∨片在线观看| 国产区二精品视| 亚洲精品乱码| 久久久久久久久久久久久久一区 | 欧美一区二区视频网站| 黄色亚洲网站| 国产精品视频九色porn| 亚洲国产一区二区精品专区| 亚洲一区激情| 午夜电影亚洲| 国产三级精品三级| 在线日韩视频| 亚洲欧美影院| 免费观看亚洲视频大全| 在线亚洲免费| 欧美二区在线| 国产一区二区精品久久| 亚洲视频在线观看| 男男成人高潮片免费网站| 亚洲一区二区精品| 欧美激情久久久| 影音先锋久久| 久久精品久久综合| 在线综合亚洲| 欧美激情一区二区三区全黄| 精品动漫一区| 久久漫画官网| 欧美一级午夜免费电影| 国产精品普通话对白| 亚洲美女在线国产| 欧美黄色片免费观看| 久久精品夜夜夜夜久久| 国产精品尤物| 午夜精品视频在线观看| 一本色道久久综合亚洲二区三区| 欧美激情综合在线| 亚洲精品午夜精品| 亚洲国产精品va在看黑人| 美女爽到呻吟久久久久| 激情成人综合| 欧美影院在线播放| 欧美一二三区精品| 国产精品美女视频网站| 亚洲一区二区不卡免费| 亚洲色图自拍| 国产欧美亚洲一区| 久久久精品欧美丰满| 亚洲综合精品| 国产精品视频区| 欧美在线视频一区二区三区| 午夜日韩电影| 一区二区亚洲精品| 欧美黄色一区| 欧美日韩中文精品| 香蕉久久夜色精品国产| 欧美在线视频在线播放完整版免费观看| 国产亚洲激情| 亚洲高清视频中文字幕| 欧美日韩国产一级片| 香蕉亚洲视频| 久久影视三级福利片| 日韩视频免费观看高清在线视频| 亚洲欧洲日韩在线| 国产精品高潮呻吟久久av无限| 欧美资源在线| 欧美粗暴jizz性欧美20| 亚洲欧美日韩人成在线播放| 久久国产精品久久精品国产| 亚洲欧洲一二三| 国产精品99久久不卡二区| 黄色成人av网站| 亚洲精品看片| 国产一区二区高清不卡| 亚洲欧洲日产国产综合网| 国产嫩草影院久久久久| 亚洲高清成人| 国产视频精品网| 欧美黑人在线观看| 国产亚洲欧美另类一区二区三区| 欧美国产日韩a欧美在线观看| 欧美三级午夜理伦三级中视频| 久久久亚洲一区| 欧美日韩精品一区二区三区| 久久久久www| 欧美日韩一二三区| 免费成人黄色片| 国产精品久久久久影院色老大| 麻豆精品精品国产自在97香蕉| 国产精品久久久999| 欧美顶级少妇做爰| 国产精品毛片| 亚洲精品乱码久久久久久久久| 国产一区久久久| 亚洲一二三区在线| 亚洲啪啪91| 久久婷婷亚洲| 久久久av网站| 国产美女高潮久久白浆| 夜夜嗨av一区二区三区网站四季av | 亚洲视频 欧洲视频| 久久久久久欧美| 欧美一区二区三区婷婷月色| 欧美不卡在线| 欧美aa国产视频| 一区二区视频在线观看| 性色av一区二区三区在线观看| 欧美一区二区三区电影在线观看 | 亚洲欧美日韩电影| 国产日韩欧美日韩| 欧美电影专区| 一区二区欧美精品| 亚洲女ⅴideoshd黑人| 欧美一区二区黄色| 欧美高清自拍一区| 欧美色另类天堂2015| 国产精品欧美日韩久久| 国内精品久久久久久| 在线观看欧美黄色| 一二三区精品福利视频| 午夜视频在线观看一区二区三区| 校园春色综合网| 最新中文字幕一区二区三区| 久久美女性网| 亚洲无人区一区| 麻豆精品一区二区综合av| 国产精品欧美日韩一区二区| 洋洋av久久久久久久一区| 乱中年女人伦av一区二区| 亚洲另类在线视频| 欧美高清影院| 日韩一级精品| 亚洲美女视频网| 欧美视频一区在线| 国产精品久久久久av| 亚洲一区二区不卡免费| 艳女tv在线观看国产一区| 欧美精品日本| 中文av一区二区| 日韩一区二区精品| 国产精品国产三级国产专播精品人| 一本色道88久久加勒比精品| 亚洲美女av网站| 欧美午夜无遮挡| 欧美日本国产精品| 亚洲天堂黄色| 久久国产婷婷国产香蕉| 最新国产の精品合集bt伙计| 亚洲欧洲日本一区二区三区| 欧美日韩国产限制| 久久精品论坛| 免费观看成人鲁鲁鲁鲁鲁视频| 一区二区动漫| 久久只精品国产| 久久国产精品久久久久久| 欧美大片第1页| 羞羞色国产精品| 欧美精品一区三区在线观看| 久久久久久日产精品| 欧美极品欧美精品欧美视频| 久久久99久久精品女同性| 欧美国产精品一区| 欧美成人精品福利| 国产一区99| 欧美一区二区三区日韩| 一本大道久久精品懂色aⅴ| 欧美a一区二区| 欧美激情第4页| 亚洲人被黑人高潮完整版| 久久久久久午夜| 欧美黄色影院| 亚洲人成欧美中文字幕| 免费久久99精品国产| 免费在线播放第一区高清av| 国产一区美女| 久久精品论坛| 欧美国产高潮xxxx1819| 亚洲三级网站| 国产精品jizz在线观看美国| 亚洲视频大全| 老**午夜毛片一区二区三区| 亚洲国产精品999|