康托展开

康托展开

康拓展开的结果为他的全排列中比他小的值得个数, 计算公式为:

ANS = A[n] * (n - 1)! + A[n-1] * (n - 2)! + ...... + A[1] * 0! //A[n]表示其位上比他小的数的个数(不能再前面出现过)

比如 465 在 其全排列中的位置为:

ans = 0 * 2! + 1 * 1! + 0 * 0! = 0 + 1 + 0 = 1

所以在其全排列中比他小的数只有一个(456)
可知465在其全排列中的位置为2

康托展开及其逆运算

const int factor[] = {1,1,2,6,24,120,720,5040,40320};
//康托展开 
int cantor(char str[])
{
    int ans = 0;
    int len = strlen(str);

    for(int i = 0; i < len; ++i)
    {
        int tmp = 0;
        for(int j = i + 1; j < len; ++j)
        {
            if(str[i] < str[j]) tmp ++; 
        }

        ans += tmp * factor[len - i - 1]; 
    }
    return ans;
}

//康拓逆展开

vector cantor_reverse(int n, int m)
{
    n--;

    vector<int> tmp, ans;

    for(int i = 1; i <= m; ++i) tmp.push_back(i);

    for(int i = m; i >= 1; ++i)
    {
        int r = n % factor[i - 1];
        int t = n / factor[i - 1];

        n = r;
        sort(tmp.begin(); tmp.end());
        ans.push_back(tmp[t]);
        tmp.erase(tmp.begin() + t);
     } 
    return ans;
 } 

参考:http://blog.csdn.net/acdreamers/article/details/7982067

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页