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

Posted taming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全排列编码于解码-康托展开式相关的知识,希望对你有一定的参考价值。

在一些问题中需要对全排列状态进行编码,如果使用完美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. }  

以上是关于全排列编码于解码-康托展开式的主要内容,如果未能解决你的问题,请参考以下文章

康托展开-全排列的编码与解码

全排列的编码与解码——康托展开 (附完整代码)

康托展开 / 逆康托展开

康托展开

康托展开 & 逆康托展开

康托展开与康托展开的逆运算