首页 > 代码库 > 求数字或者字符串的全排列

求数字或者字符串的全排列

以数字举例:有一个数组A的数为 :1 2 3 4 ,其按字典序列的全排列为:

1 2 3 4
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 4 1
……….

总共有 n!个排列,现在输入一个数K,输出其第K的排列

方法:采用康托编码的思想,其实就是求出每个位置上的数字:第一个位置的数字,第二个位置的数字。。。。

解法:按顺序求出每个位置上的数,这边假设 K=8 ;数组为:1 2 3 4 ,长度为4,位置p代表数组中第P个数:p=k/ (n-1)!
1、求第一个位置上的数,p代表第一个数在数组A中的位置

1)  p=8/(4-1)!=8/6=1; ---------->第一个数即  A[1]=2
 2) 把 A[1] 从数组A中去掉,剩下的数为:1 3 4
 3) k=k%(4-1)!=8%6=2

2、重复 步骤 1 的过程,求第二个位置上的数:

1)此时 k =2,数组A变为:1 3 4,数组的长度为3
 2)p=1/(3-1)!=2/2=1; ---------->第二个数即  A[1]=3
 3)把A[1]从数组A中去掉,剩下的数为:1 4
 4)k=k%(3-1)!=2%2=0

3、求第3个位置上的数,仍然重复步骤1 的过程:

1)此时K=0,循环结束;结束前,我们要把剩下的位置的数进行确定!
  其实很简单:无需任何操作,就是将数组A中剩下的元素按逆序输出:此时数组A中剩下的数字为:1、4;
  所以结果序列中第三个数 4,第四个数  1

循环结束的条件为:K=0

最后的结果:第 8 个序列是:2 3 4 1

代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int getNjiecheng(int n){
     int res=1;
     for(int i=1;i<=n;i++){
          res*=i;
     }
     return res;
}
vector<int> getPermutationSequence(int k,vector<int> v){
     vector<int> res;
     int n=v.size();
     if(k>getNjiecheng(n))return res;
     while(k>0){
          int j=getNjiecheng(n-1);
          int p = k/j;
          k=k%j;
          if(k==0){
               p-=1;
               res.push_back(v[p]);
               vector<int>::iterator iter=v.begin()+p;
               v.erase(iter);
               reverse(v.begin(),v.end());
               for(int i=0;i<v.size();i++) res.push_back(v[i]);
               return res;
          }
          else{ 
               res.push_back(v[p]);
               vector<int>::iterator iter=v.begin()+p;
               v.erase(iter);
               n--;
          }
     }
}
int main(){
     vector<int> v;
     for(int i=1;i<=4;i++)
          v.push_back(i);
     vector<int> res=getPermutationSequence(24,v);
     for(vector<int>::iterator iter=res.begin();iter!=res.end();iter++){
          cout<<*iter<<"  ";
     }
     cout<<endl;
     return 0;
}

如果我们想得到 n!个全排列:只需循环 N! 次,调用getPermutationSequence(25,v);

for(int i=1;i<=N!;i++){
     getPermutationSequence(i,v);
}

求数字或者字符串的全排列