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

以数字举例:有一个数组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

代码: <!-- lang: cpp --> #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);

<!-- lang: cpp -->
    for(int i=1;i<=N!;i++){
         getPermutationSequence(i,v);
    }

转载于:https://my.oschina.net/mopidick/blog/324741

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值