码迷,mamicode.com
首页 > 其他好文 > 详细

全排列编码于解码-康托展开式

时间:2018-03-10 15:56:45      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:nbsp   stream   title   class   href   cout   --   公式   cli   

在一些问题中需要对全排列状态进行编码,如果使用完美hash来实现的话需要编码数量在计算机承受范围内,康托展开式符合条件

公式:X=An*(n-1)!+An-1*(n-2)!+......A2*1!+A1*0!

其中An等于在剩余元素中当前元素第几大(从0开始)。
比如:1 4 2 6 5 3 7 8 9

1在剩下的1 4 2 6 5 3 7 8 9中为第0大

4在剩下的4 2 6 5 3 7 8 9中为第2大

2在剩下的2 6 5 3 7 8 9中为第0大

..........

8在8 9中为第0大

9在9中为第0大

则编码为0*8!+2*7!+0*6!+2*5!+1*4!+0*3!+0*2!+0*1!+0*0!=10344

解码          

辗转对n!作商和取余,商代表下一个位置元素在未选出元素中排第几大,举例

10344/8!=0

10344%8!=10344

10344/7!=2

10344%7!=264

264/6!=0

264%6!=264

264/5!=2

264%5!=24

24/24!=1

24%24=0

0/3!=0

.........

0%0!=0

1在1 2 3 4 5 6 7 8 9中排第0大

4在2 3 4 5 6 7 8 9中排第2大

2在2 3 5 6 7 8 9中排第0大

6在3 5 6 7 8 9中排第2大

5在3 5 7 8 9中排第1大

3在3 7 8 9中排第0大

7在7 8 9中排第0大

8在8 9中排第0大

9在9中排第0大

所以10344对应的排列为1 4 2 6 5 3 7 8 9

代码:

 

[cpp] view plain copy
 
    1. #include<iostream>  
    2. #include<vector>  
    3. using namespace std;  
    4.   
    5.   
    6. const long long maxN=363000;  
    7. const long long p[]={1,1,2,6,24,120,720,5040,40320};  
    8.   
    9. long long coding(int* u){  
    10.    long long code=0;  
    11.    for(int i=0;i<9;i++){  
    12.       int k=0;  
    13.       for(int j=i+1;j<9;j++)if(u[i]>u[j])k++;  
    14.       code+=k*p[8-i];  
    15.    }  
    16.    return code;  
    17. }  
    18.   
    19. vector<int> decoding(long long code){  
    20.    bool vis[9]={0};  
    21.    vector<int> ans;  
    22.    for(int i=8;i>=0;i--){  
    23.       int u=code/p[i],v=0;code%=p[i];  
    24.       while(u>=0){  
    25.          if(vis[v]==false)u--;  
    26.          v++;  
    27.       }  
    28.       ans.push_back(v);  
    29.       vis[v-1]=true;  
    30.    }  
    31.    return ans;  
    32. }  
    33.   
    34. int main(){  
    35.    int u[]={1,4,2,6,5,3,7,8,9};  
    36.    int code=coding(u);  
    37.    vector<int> ans=decoding(code);  
    38.    cout<<"code:"<<code<<endl<<"decode:";  
    39.    for(int i=0;i<ans.size();i++)cout<<ans[i]<<‘ ‘;  
    40. }  

全排列编码于解码-康托展开式

标签:nbsp   stream   title   class   href   cout   --   公式   cli   

原文地址:https://www.cnblogs.com/TAMING/p/8538874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!