康托展开 & 逆康托展开(计算一个序列的对应的值)

ε祈祈猫儿з 提交于 2020-01-24 16:11:34

1、康拓展开:

一个序列长度为n,是1~n的数字的全排列中的一种,求出这个序列对应的全排列中序列的编号就是康拓展开,

即将一个全拍列的序列转化为一个数字编号。

 

代码:

int cantor(int a[],int n) //序列a的下标从0~n-1
{
    int ans = 0;
    for(int i=0;i<n;i++)
    {
        int x = 0,c = 1,m = 1;
        for(int j=i+1;j<n;j++)
        {
            if(a[j]<a[i]) x++;
            m *= c; c++;
        }
        ans += x*m;
    }
    return ans;
}

 

2、逆康拓展开

将一个数字编号转化为一个长度为n的全排列的序列,eg:x = 1时代表的序列为1 2 3 4 5,一次类推。

 

代码:

int fac[120],b[120];
bool vis[120];
void decantor(int x,int n)
{
    fac[0] = 1;
    for(int i=1;i<=n;i++) fac[i] = fac[i-1]*i,vis[i] = false;
    x--;//如果从1开始
    for(int j,i=0;i<n;i++)
    {
        int t = x/fac[n-1-i];
        for(j=1;j<=n;j++)
        if(vis[j] == false){
            if(t == 0) break;
            t--;
        }
        b[i] = j;
        vis[j] = true;
        x %= fac[n-1-i];
    }
    //得到b数组就是要求的序列。
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!