求第N个排列数

设序列为N个M位数的基本数字组成的排列数(N<=M)

假设序列是有序的,求第n个排列数(以0开始索引,0<=n<N!)

 

ContractedBlock.gif ExpandedBlockStart.gif GetNofP
void GetNofP(char const * const in,char* out,int const size,unsigned long long N)
//in必须为递增的序列,size为in的大小
//out为结果序列,out的大小必须大于size
//0<=N<size!

{
strcpy(out,in);
vector<unsigned long long > info(size);
int pos = size -1;
info[pos] = 1;
int i =1;
--pos;
while(pos>=0)
{
info[pos] = info[pos+1]*i;
++i;
--pos;
}
for(int i = 0;N!=0&&i<size;++i)
{
unsigned long cur =(unsigned long) (N/info[i]);
if(cur==0)
continue;
int newPos = i+cur;
int curVal =out[i];
out[i] = out[newPos];
--newPos;
while(newPos>i)
{
out[newPos+1]=out[newPos];
--newPos;
}
out[i+1] = curVal;
N = N%info[i];
}
}

测试代码

ContractedBlock.gif ExpandedBlockStart.gif 测试代码
int main(int argc, char* argv[])
{
char arr[] = "1234";
char out[sizeof(arr)];
unsigned long long sum =0;
int size =sizeof(arr)/sizeof(arr[0]) -1;
sum=1;
for(int i=1;i<=size;++i)
{
sum*=i;
}
int beg = GetTickCount();
for(unsigned long long i=0;i<sum;++i)
{
GetNofP(arr,out,size,i);
cout<<out<<endl;
}
int end = GetTickCount();
cout<<(end - beg)<<endl;
cout<<sum<<endl;

return 0;
}
ContractedBlock.gif ExpandedBlockStart.gif 输出结果
1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321
0
24
请按任意键继续. . .




转载于:https://www.cnblogs.com/SammyLan/archive/2011/10/13/2210520.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值