字串的全排列

iDotNetSpace發表於2009-08-12
問題如下:
給定字串,比如char *s = "abc",請用裡面的字元做全排列,即求'a','b,'c'的全排列,其結果應該是"abc","acb","bac","bca","cab","cba"一共六種.
這個問題比較容易想到的解決方案是使用遞迴,要求以'a'開頭的"abc"的全排列,可以先求"bc"的全排列,然後再加上'a'即可,"bc"一共有兩種全排列,"bc","cb"故以'a'開頭的全排列就是"abc","acb",以此類推,再分別求出以'b','c'開頭的全排列即可.故歸納起來演算法如下:

void Permute(strInput,strOutput,recursLev)
1 n 2 if recurLev = n
3      then print strOutput;
4      return;
5 for i 6      do if strInput[i] has been used //used[i]
7          go to step 5, operate the next characater.
8      else
9          do strOutput[recursLev] 10        used[i] 11        Permute(strInput,strOutput,recursLev+1)
12        used[i]

下面是我用C實現的上述算了,增加了一個包裝類,分配了三個陣列並對輸入字串做了一些處理.

int Permute(char inString[])
{
     int length,i,*used;
     char *out;

     length = strlen(inString);
     ut = (char *)malloc(length +1);
     if(!out)
     return 0;

     out[length] = '\0';
     used = (int *)malloc(sizeof(int) * length);
     if(!used)
     return 0;
     for(i = 0;i
    {
        used[i] = 0;
    }

    DoPermute(inString,out,used,length,0);
    free(out);
    free(used);
    return 1;

}

 void DoPermute(char in[],char out[],int used[],int length,int recursLev)
{
     int i;
     if(recursLev == length)
     {
          printf("%s\n",out);
          return;
     }
   for(i = 0; i
   {
        if(used[i])
              continue;
        out[recursLev] = in[i];
        used[i] =1;
        DoPermute(in,out,used,length,recursLev+1);
        used[i] = 0;
    }
 }
 
上面的程式碼不能正解處理字串中有重複字元的情況,即輸出結果有可能有重複.如果字串中有重複字元,可以先對字串裡面的字元進行排序,然後再呼叫DoPermute函式.只要對DoPermute方法做一點小小的改動即可,新增一輔助變數用以記錄前一步操作的字元並與當前字元比較,如果當前字元與之不同並且還未被使用,則對其進行全排列

void DoPermute(char in[],char out[],int used[],int length,int recursLev)
{
     int i;

     char preChar;

     if(recursLev == length)
     {
         printf("%s\n",out);
         return;
     }
     preChar = 0;
     for(i = 0; i
     {
          if(used[i] ==0 &&in[i]!=preChar)
          {
                  preChar = in[i];
                  out[recursLev] = in[i];
                  used[i] =1;
                  DoPermute(in,out,used,length,recursLev+1);
                  used[i] = 0;
           }
   
      }
 
}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-612016/,如需轉載,請註明出處,否則將追究法律責任。

相關文章