【100题】第五十三题 字符串的全排列

递归求解思路:

1)  每个元素依次放到首位,然后对其余元素递归

2)  当当前元素到达末尾的时候,输出该序列

关键是:

      每个元素交换完,之后要交换过来。每个元素依次放到首位,

      for(int i=currentIndex;i<=n;++i){ swap  从i+1递归  swap  }

 

#include<stdio.h>
#include<stdlib.h>
#define SWAP(x,y,t)((t)=(x),(x)=(y),(y)=(t))
int score=0;
void perm(int *list,int i,int n)
{
        int j,temp;
 
        if(i==n)
        {
            for(j=0;j<=n;j++)
            {
         printf("%d ",list[j]);
            }
            printf("\n");
            score++;
        }
        else
        {
                for(j=i;j<=n;j++)
                {
                     SWAP(list[i],list[j],temp);
                     perm(list,i+1,n);
                       SWAP(list[i],list[j],temp);
                }
        }
}
int main()
{
        int list[]={1,2,3};
        perm(list,0,2);
         printf("Thetotal number is %d\n",score);
        system("pause");
}


 

String 版本

 

#include <iostream>
using namespace std;
 
void Permutation(string pStr, int k, int n)
{
     if(k==n)
           cout<<pStr<<endl;
             
     for(int i=k;i<n;++i)
           {
                 swap(pStr.at(i),pStr.at(k));
                          Permutation(pStr, k+1,n);
                          swap(pStr.at(i),pStr.at(k));
                       
       }     
          
}
 
int main()
{
         strings="abcdef";
         Permutation(s,0,s.length());
}


 

二,扩展

如果不是求字符的所有排列,而是求字符的所有组合,应该怎么办呢?(P72
   

思路:这里不采用交换方式,而是采用删减的方式。采用不同的剔除顺序,并用prex保留删减值,这样将得到所有符合条件的序列

  

#include  <iostream>
using namespacestd;
voidselect(string str, string prex)
{
      string temp=str;
      cout<<prex<<endl;
      for(int i=0;i<str.length();++i)
           {
                   select(str.erase(i,1),prex+str.at(i));
               str=temp;
                       
        }     
          
}
 
int main()
{
          string s="abcd";
          select(s,"");
}


扩展二:

当输入的字符串中含有相同的字符串时,相同的字符交换位置是不同的排列,但是同一个组合。
    
举个例子,如果输入aaa,那么它的排列是6aaa,但对应的组合只有一个。

posted @ 2012-08-22 22:08  MXi4oyu  阅读(197)  评论(0编辑  收藏  举报