字符串面試題系列之七:字符串全排列


編譯環境

   本系列文章所提供的算法均在以下環境下編譯通過。

【算法編譯環境】Federa 8,linux 2.6.35.6-45.fc14.i686
【處理器】 Intel(R) Core(TM)2 Quad CPU Q9400 @ 2.66GHz
【內存】 2025272 kB

前言

    這是一道排列組合的題目。對於排列組合的題目在面試當中也是十分常見,主要考察小伙伴們的思維的有序性和解決問題的能力。本題就曾出自騰訊的筆試當中。一般這類題目大家做的時候用樹的方式來幫助思考會有一些效果。

    本系列文章均系筆者所寫,難免有一些錯誤或者紕漏,如果小伙伴們有好的建議或者更好的算法,請不吝賜教。

正文

【題目】

   輸入一個字符串,打印出該字符串中字符的所有排列。

【例子】

   輸入字符串abc,則輸出由字符a、b、c所能排列出來的所有字符串abc、acb、bac、bca、cab和cba。

【分析】

   這是一道排列組合的題目。而做排列組合的時候頭腦要保持清醒並且有序。我們列舉一個例子,假設有字符串abc,如果我們手動排列,過程是怎樣的呢?

   一般人的分析習慣總是把大問題化成小問題來解決。這是我們的習慣。
首先保持a在第一位不動,我們看子字符串bc,bc的排列是bc和cb,這樣我們得到結果是abc,acb ;
其次保持b在第一位不東,我們看子字符串ac,ac的排列是ac和ca,這樣我們得到結果是bac,bca ;
再次保持c在第一位不東,我們看子字符串ab,ab的排列是ab和ba,這樣我們得到結果是cab,cba
這樣我們都得到三個字符的排列是abc,acb,bac,bca,cab,cba。這樣思維是不是很清晰。

   參照上面的手工做法,我們如何用程序去實現呢。顯然用遞歸的方式更符合我們的思維。

第一步:當字符串只有1個字符的時候,其排列是字符本身。
第二步:遞歸求出子字符串的排列
第三步:算法結束。

【代碼】

#include <iostream>
#include <cstring>

#define swap(a, b) { char c=a; a=b; b=c; }

void string_permutation( char * const string, int start, int end )
{
   if( start == end )
   {
      std::cout << string << std::endl;
   }
   else
   {
      for( int i = start; i < end; i++)
      {
         // swap two characters
         swap( string[i], string[start] );
         string_permutation( string, start + 1, end );
         // recover
         swap( string[i], string[start] );
      }
   }
}

int main( int argc, char ** argv )
{
   char string[] = "abcd";
   string_permutation( string, 0, strlen(string) );
   return 0;
}

【結論】

   我們輸入字符串abcd,應該有16種排列組合的方式。得到的結果如下:

11

作者

   出處:http://www.cnblogs.com/gina

   本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM