• <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>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            第十六章、全排列問題

            53.字符串的排列。
            題目:輸入一個(gè)字符串,打印出該字符串中字符的所有排列。
            例如輸入字符串a(chǎn)bc,則輸出由字符a、b、c 所能排列出來的所有字符串
            abc、acb、bac、bca、cab 和cba。

                分析:此題最初整理于去年的微軟面試100題中第53題,第二次整理于微軟、Google等公司非常好的面試題及解答[第61-70題] 第67題。無獨(dú)有偶,這個(gè)問題今年又出現(xiàn)于今年的2011.10.09百度筆試題中。ok,接下來,咱們先好好分析這個(gè)問題。

            • 一、遞歸實(shí)現(xiàn)
              從集合中依次選出每一個(gè)元素,作為排列的第一個(gè)元素,然后對剩余的元素進(jìn)行全排列,如此遞歸處理,從而得到所有元素的全排列。以對字符串a(chǎn)bc進(jìn)行全排列為例,我們可以這么做:以abc為例
              固定a,求后面bc的排列:abc,acb,求好后,a和b交換,得到bac
              固定b,求后面ac的排列:bac,bca,求好后,c放到第一位置,得到cba
              固定c,求后面ba的排列:cba,cab。代碼可如下編寫所示:
            1. template <typename T>  
            2. void CalcAllPermutation_R(T perm[], int first, int num)  
            3. {  
            4.     if (num <= 1) {  
            5.         return;  
            6.     }  
            7.       
            8.     for (int i = first; i < first + num; ++i) {  
            9.         swap(perm[i], perm[first]);  
            10.         CalcAllPermutation_R(perm, first + 1, num - 1);  
            11.         swap(perm[i], perm[first]);  
            12.     }  
            13. }  
                或者如此編寫,亦可:
            1. void Permutation(char* pStr, char* pBegin);  
            2.   
            3. void Permutation(char* pStr)  
            4. {  
            5.       Permutation(pStr, pStr);  
            6. }  
            7.   
            8. void Permutation(char* pStr, char* pBegin)  
            9. {  
            10.     if(!pStr || !pBegin)  
            11.         return;  
            12.       
            13.     if(*pBegin == '\0')  
            14.     {  
            15.         printf("%s\n", pStr);  
            16.     }  
            17.     else  
            18.     {  
            19.         for(char* pCh = pBegin; *pCh != '\0'; ++ pCh)  
            20.         {  
            21.             // swap pCh and pBegin  
            22.             char temp = *pCh;  
            23.             *pCh = *pBegin;  
            24.             *pBegin = temp;  
            25.               
            26.             Permutation(pStr, pBegin + 1);    
            27.             // restore pCh and pBegin  
            28.             temp = *pCh;  
            29.             *pCh = *pBegin;  
            30.             *pBegin = temp;  
            31.         }  
            32.     }  
            33. }  
            • 二、字典序排列
              把升序的排列(當(dāng)然,也可以實(shí)現(xiàn)為降序)作為當(dāng)前排列開始,然后依次計(jì)算當(dāng)前排列的下一個(gè)字典序排列。
              對當(dāng)前排列從后向前掃描,找到一對為升序的相鄰元素,記為i和j(i < j)。如果不存在這樣一對為升序的相鄰元素,則所有排列均已找到,算法結(jié)束;否則,重新對當(dāng)前排列從后向前掃描,找到第一個(gè)大于i的元素k,交換i和k,然后對從j開始到結(jié)束的子序列反轉(zhuǎn),則此時(shí)得到的新排列就為下一個(gè)字典序排列。這種方式實(shí)現(xiàn)得到的所有排列是按字典序有序的,這也是C++ STL算法next_permutation的思想。算法實(shí)現(xiàn)如下:
            1. template <typename T>  
            2. void CalcAllPermutation(T perm[], int num)  
            3. {  
            4.     if (num < 1)  
            5.         return;  
            6.           
            7.     while (true) {  
            8.         int i;  
            9.         for (i = num - 2; i >= 0; --i) {  
            10.             if (perm[i] < perm[i + 1])  
            11.                 break;  
            12.         }  
            13.           
            14.         if (i < 0)  
            15.             break;  // 已經(jīng)找到所有排列  
            16.       
            17.         int k;  
            18.         for (k = num - 1; k > i; --k) {  
            19.             if (perm[k] > perm[i])  
            20.                 break;  
            21.         }  
            22.           
            23.         swap(perm[i], perm[k]);  
            24.         reverse(perm + i + 1, perm + num);  
            25.          
            26.     }  
            27. }  
              擴(kuò)展:如果不是求字符的所有排列,而是求字符的所有組合,應(yīng)該怎么辦呢?當(dāng)輸入的字符串中含有相同的字符串時(shí),相同的字符交換位置是不同的排列,但是同一個(gè)組合。舉個(gè)例子,如果輸入abc,它的組合有a、b、c、ab、ac、bc、abc

            轉(zhuǎn)自
            http://blog.csdn.net/v_july_v/article/details/6879101

            久久精品国产99国产精品亚洲| 亚洲精品美女久久久久99小说 | 伊人久久大香线蕉av一区| 99久久久精品| 精品久久久中文字幕人妻| 麻豆亚洲AV永久无码精品久久 | 久久午夜伦鲁片免费无码| 久久99精品国产| 性做久久久久久久| 久久福利资源国产精品999| 久久成人18免费网站| 亚洲午夜久久久精品影院| 波多野结衣中文字幕久久| 熟妇人妻久久中文字幕| 国产—久久香蕉国产线看观看| 午夜不卡888久久| 蜜臀av性久久久久蜜臀aⅴ| 久久人人爽人人爽人人片AV东京热| 国产精品青草久久久久婷婷| 亚洲色大成网站WWW久久九九| 久久99精品久久久久久噜噜| 久久99热国产这有精品| 久久久久久久久久久久中文字幕| 久久久无码一区二区三区| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 波多野结衣中文字幕久久| 国产精品久久久久a影院| 久久久精品国产亚洲成人满18免费网站 | 狠狠色综合久久久久尤物| 久久综合久久综合九色| 久久久久99精品成人片三人毛片| 国产精品禁18久久久夂久| AV色综合久久天堂AV色综合在| 无码人妻精品一区二区三区久久久| 久久久久久国产a免费观看黄色大片 | 国产亚洲精午夜久久久久久| 久久99热精品| 99热热久久这里只有精品68| 久久久久久久综合日本亚洲| 久久国产精品免费一区| 欧美日韩中文字幕久久久不卡|