精华内容
下载资源
问答
  • Cantor展开

    2018-05-04 22:01:45
    int FACT[]={1,1,2,6,24,120,720,5040,40320,...int cantor(int a[],int n) { int x=0; for(int i=0;i<n;i++) { int tot=0; for(int j=i+1;j<n;j++) { if(a[j]<a[i]) tot++...

     

    int FACT[]={1,1,2,6,24,120,720,5040,40320,362880};//计算阶乘
    int cantor(int a[],int n)
    {
    	int x=0;
    	for(int i=0;i<n;i++)
    	{
    		int tot=0;
    		for(int j=i+1;j<n;j++)
    		{
    			if(a[j]<a[i])
    			tot++;
    		}
    		x+=tot*FACT[n-i-1];
    	}
    	return x;
    }
    void uncantor(int n,int num)
    {//逆康托展开
        int b[10],x;//b表示剩下的数,并且按升序排列 
        for(int i=0;i<n;i++)
    	b[i]=i+1;
        for(int i=0;i<n;i++)
    	{
            x=num/FACT[n-i-1];
    		num%=FACT[n-i-1];
    		a[i]=b[x];//x表示在当前数之前,比当前数小的数有x个,当前数为b[x];
            for(int j=x;j<n;j++)
    		b[j]=b[j+1];//删去已选数x
        }
    }

     

    展开全文
  • 做到HDOJ1043的时候接触到了Cantor展开式,因为开始在用BFS+hash 做的,因此在四向搜索的时候需要判重,需要知道 当前方向的这种九宫情况是否之前被访问过,但是...九宫的总情况大概有9!个36W多个,因此判重非常的...

    做到HDOJ1043的时候接触到了Cantor展开式,因为开始在用BFS+hash 做的,因此在四向搜索的时候需要判重,需要知道

    当前方向的这种九宫情况是否之前被访问过,但是...九宫的总情况大概有9!个36W多个,因此判重非常的烦,看了网上的

    基本都是手写的,用数组模拟 hash table ,hash 最重要的就是hash函数来得到序列号,因为九宫不存在重复数,因此每种

    情况可以当做一个全排序,因此Cantor来了...通过这下列操作可以得出每一种九宫情况的序列号而不会重复,来作为hash

    序列号..很nice的操作!

    Cantor展开:

    X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a2*1!+a1*0!

    使用示例来帮助理解利用Cantor展开如何求解本问题。 
    假如序列s=[“A”,”B”,”C”,”D”] 
    需要求序列s’=[“D”,”A”,”B”,”C”]是序列s的全排列中的第几个排列,记作X(s’);

    X(s’) =     3(在序列DABC中有3个比D小)*3!+
                0(在剩下的序列ABC中有0个比A小)*2!+
                0(在剩下的序列BC中有0个比B小)*1!+
                0(在剩下的序列C中有0个比C小)*0!
        =18

    那么序列s’是s的全排列中第18个排列(从0开始计数); 
    同理可以根据s算第18个排列序列。 

    总结:康托展开是一个全排列到一个自然数的一一映射

    下列代码转自 https://www.cnblogs.com/AdaByron/archive/2011/09/21/2200970.html 

    正向展开:

    //value数组存放当前排列   
    const int fac[]={1,1,2,6,24,120,720,5040,40320};//康托序列   
    inline int cantor(){  
        int ans=0;  
        for(int i=0;i<N;i++)  
        {  
            int cnt=0;  
            for(int k=i+1;k<N;k++)  
            {  
                if(value[k]<value[i])  
                    cnt++;  
            }  
            ans+=fac[8-i]*cnt;  
        }  
        return ans;  
    }

    反向展开:

    //value数组存放当前排列   
    const int fac[]={1,1,2,6,24,120,720,5040,40320};//康托序列   
    inline int cantor(Point p){  
        int ans=0;  
        for(int i=0;i<N;i++)  
        {  
            int cnt=0;  
            for(int k=i-1;k>=0;k--)  
            {  
                if(value[k]>value[i])  
                    cnt++;  
            }  
            ans+=fac[i]*cnt;  
        }  
        return ans;  
    }

     

    展开全文
  • Cantor展开、全排列问题、魔板问题(JAVA实现)本文由全排列问题的递归和非递归写法入手,引出Cantor展开的公式及其应用,最后讨论Cantor数的经典应用之魔板问题 全排列问题 Cantor展开及其逆展开 魔板问题 问题:...

    Cantor展开、全排列问题、魔板问题(JAVA实现)

    本文由全排列问题的递归和非递归写法入手,引出Cantor展开的公式及其应用,最后讨论Cantor数的经典应用之魔板问题

    • 全排列问题
    • Cantor展开
    • 魔板问题

    目录

    问题:给定字符串S[0…N-1],设计算法,枚举S的全排列

    以一个简单的示例来表示解题过程
    示例 枚举0123的全排列
    0123 0132 0213 0231 0312 0321
    1023 1032 1203 1230 1302 1320
    2013 2031 2103 2130 2301 2310
    3012 3021 3102 3120 3201 3210
    手动写出这些序列的时候,实际上是脑补了一个树形结构,如下:
    这里写图片描述
    画出这个树的过程实际上是一个深度搜索的过程,每次到达叶子节点时就产生一个输出,之后再回溯,搜索下一个叶子节点。
    深度搜索的过程实际上就是一个入栈出栈的过程,也就是一个递归过程。

    全排列之递归解法

    使用递归时,代码结构是很清晰,也容易理解,便不再赘述,直接上代码。

    //无重复的全排列递归写法
    public class Permutation {
        public static final int N = 4;
        public static void main(String[] args){
            //初始化
            int[] sequence = new int[N];
            for(int i = 0;i < N;i++){
                sequence[i] = i+1;
            }
            permutation(sequence,N,0);
        }
    
        private static void print(int[] sequence){
            for(int i : sequence){
                System.out.print(i);
            }
            System.out.println();
        }
    
        private static void swap(int[] sequence,int i, int j){
            int tmp = sequence[i];
            sequence[i] = sequence[j];
            sequence[j] = tmp;
        }
        //固定前n位的全排列
        public static void permutation(int[] sequence, int size, int n){
            if(n == size - 1) print(sequence);
    
            for(int i = n; i < size;i++){
                //用其他位来交换第n位
                swap(sequence,i,n);
                permutation(sequence,size,n+1);
                swap(sequence,i,n);
            }
        }
    }

    当出现重复元素时,在用其他位交换第n位时,会有相同的两个位均与n位发生了交换。所以我们需要在交换时判断该位是否在之前已经被放置到n位过。
    为了判断某个元素是否已经被访问过,另增加一个duplication数组。
    与无重复元素的序列全排列相比,仅在permutation函数中增加了一个参数及两行代码。
    代码如下

    //有重复的递归写法
    public class PermutationWithDuplicate {
        public static final int N = 4;
    
        public static void main(String[] args){
            //初始化
            int[] sequence = {1,2,3,4};
            boolean[] duplication = new boolean[N];
            permutation(duplication,sequence,N,0);
        }
    
        private static void print(int[] sequence){
            for(int i : sequence){
                System.out.print(i);
            }
            System.out.println();
        }
    
        private static void swap(int[] sequence,int i, int j){
            int tmp = sequence[i];
            sequence[i] = sequence[j];
            sequence[j] = tmp;
        }
    
        public static void permutation(boolean[] duplication,int[] sequence,int size,int n){
    
            //遍历每一根隐式树时,duplication的状态应该是要刷新的
            //所以duplication不能作为全局变量,这样会导致所有递归状态共用一个duplication
    
            //如果作为局部变量,那么每次调用permutation都需要重新创建这个数组,并且这个数组不会被全部访问到,耗费了时间和空间
            //所以作为参数在递归状态间传递,注意在回溯时需要恢复第n位,以及duplication数组。
            //因为非基本数据类型的参数都是传址引用,如果不恢复duplication的值,那么会导致所有递归状态共用一个duplication
    //      boolean[] duplication = new boolean[N];
            if(n == size-1){
                print(sequence);
            }
            for(int i = n;i < size;i++){
                if(!duplication[(sequence[i]%N)]){
                    duplication[(sequence[i]%N)] = true;
                    swap(sequence,i,n);
                    permutation(duplication,sequence,size,n+1);
                    swap(sequence,i,n);
                    duplication[(sequence[i]%N)] = false;
                }
            }
        }
    }

    全排列之非递归解法

    如果是对1234字符串,枚举其所有排列。相当于就是把由1、2、3、4构成的数字全部列举出来。既要列举,自然有个顺序,不妨从小到大列举。
    1234 1243 1324 1342 1423 1432
    2134 2143 2314 2341 2413 2431
    3124 3142 3214 3241 3412 3421
    4123 4132 4213 4231 4312 4321

    每一次迭代,我们都希望获取比当前的序列稍大的序列。而比当前的序列稍大的序列仅仅只与当前的序列相关,也就是通过当前的permutation,我们能立刻得到next permutation.了解了这个原理后,程序的框架便出来了。

    while(hasNextPermutation){
        getNextPermutation();
        print;
    }

    可以看到,当某个序列从首位到末位是依次递减时,是不可能再增大的。
    反之,当某个序列的低位比高位大时,可以将低位和高位交换,交换后,将此高位后的所有位数重新按次序排列得到新的序列。举例来讲,比如1342,从末位2往前遍历,4比3大,将4与3交换变为1432,再将4后面的32按从小到大的次序变为23,最后得到next permutation为1423。
    代码如下:

    public class NextPermutation {
        public static final int N = 4;
        public static void main(String[] args){
            //初始化
            int[] sequence = new int[N];
            for(int i = 0;i < N;i++){
                sequence[i] = i+1;
            }
            permutation(sequence);
        }
        public static void permutation(int[] sequence){
            print(sequence);
            int[] tmp = getNextPermutation(sequence);
            while(null != tmp){
                print(tmp);
                tmp = getNextPermutation(tmp);
            }
        }
        private static void print(int[] sequence){
            for(int i : sequence){
                System.out.print(i);
            }
            System.out.println();
        }
    
        private static void swap(int[] sequence,int i, int j){
            int tmp = sequence[i];
            sequence[i] = sequence[j];
            sequence[j] = tmp;
        }
    
        public static int[] getNextPermutation(int[] sequence){
            int scriptOfNeedSwap = 0;
            int i;
            //从后往前找
            for(i = N - 1;i >= 1;i--){
                if(sequence[i] > sequence[i-1]){
                    scriptOfNeedSwap = i - 1;
                    break;
                }
            }
    
            if(i == 0) return null;
            //找到第一个递减的位置,交换
            for(i = N - 1;i > scriptOfNeedSwap;i-- ){
                if(sequence[i] > sequence[scriptOfNeedSwap]){
                    swap(sequence,i,scriptOfNeedSwap);
                    break;
                }
            }
            //可以看到一个规律,交换之后后面的几位均是降序的,此时只需要对其进行翻转即可
            //翻转
            for(i = N-1;i > scriptOfNeedSwap;i--){
                swap(sequence,i,++scriptOfNeedSwap);
                if(i <= scriptOfNeedSwap) break;
            }
    
            return sequence;
        }
    }

    本解法对于有重复元素的序列是完全适用的,按从小到大的顺序将序列打印出来,天然就能达到去重的目的。

    问题:如何计算N个无重复元素的某个排列是第几个排列

    如何求解这个问题。很自然的想到,使用从小到大的顺序枚举出一个数列的所有排列,直到匹配目标排列。
    然而Cantor展开使用公式解决了这个问题。

    Cantor展开

    关于Cantor展开的原理这里不作详细介绍。Cantor展开的公式为:

    X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a2*1!+a1*0!

    使用示例来帮助理解利用Cantor展开如何求解本问题。
    假如序列s=[“A”,”B”,”C”,”D”]
    需要求序列s’=[“D”,”A”,”B”,”C”]是序列s的全排列中的第几个排列,记作X(s’);

    X(s’) =     3(在序列DABC中有3个比D小)*3!+
                0(在剩下的序列ABC中有0个比A小)*2!+
                0(在剩下的序列BC中有0个比B小)*1!+
                0(在剩下的序列C中有0个比C小)*0!
        =18

    那么序列s’是s的全排列中第18个排列(从0开始计数);
    同理可以根据s算第18个排列序列。

    总结:康托展开是一个全排列到一个自然数的一一映射

    魔板问题

    在下面对求解魔板问题的过程中应用了隐式树的思想以及Cantor展开。
    问题描述:
    在魔方风靡全球之后不久,Rubik先生发明了它的简化版――魔板。魔板 由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方 向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:
      1 2 3 4
      8 7 6 5
      对于魔板,可施加三种不同的操作,具体操作方法如下:
      A: 上下两行互换,如上图可变换为状态87654321
      B: 每行同时循环右移一格,如上图可变换为41236785
      C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
      给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。

    在杭电的OJ上有这样一个题,读者可以作为练习。题目链接

    解题思路

    魔板的每一种状态,实际上是序列12345678的一种全排列,最多可以有8!=40320种状态。
    而魔板问题则是求解状态x最快可以经过多少个状态到达状态y。
    我们也可以脑补出一棵三叉树,编号为1的状态经过A,B,C三种行为到达状态2,3,4。2,3,4再分别经过A,B,C三种行为扩展出更多的状态。
    与最开始的全排列问题不同的是,在遍历这棵树的时候,我们采用的是广度优先搜索的方法,将这棵树做层次遍历,从根节点出发,到达某个节点所需要的最少的变换次数则是这个节点所在的层数。所以,当做广度优先搜索遍历,找到第一个满足条件的状态时,程序就可以返回了。
    确定了广度优先搜索的算法,便可以确定数据结构采用先入先出的队列了。每扩展出新的节点,便将这些新的节点加入到队列中,等待被取出后再度扩展。
    在遍历过程中,我们可以考虑做一些优化。

    • 判重。判断某个节点的状态是否已经遍历过,若已经遍历过,则无需再扩展此节点
    • 剪枝。 AA,BBBB,CCCC这样的变换路径都是没有必要的,会变回原本的状态

    由Cantor展开,可以将魔板的每一钟状态映射为一个自然数,这就可以作为判重的依据。而计算Cantor数需要计算阶乘,对阶乘进行优化也是必须的,可以用一个hash数组将需要计算的阶乘事先保存下来。

    具体代码如下:

    public class MoBanProblem {
        static int[] hash = {1,1,2,6,24,120,720,5040};
        public static void main(String args[]){
            String number = "12345678";
            String end = "34512678";
            String rs = null;
            number = preProcess(number);
            end = preProcess(end);
            rs = bfs(number,end);
            if(rs != null){
                System.out.println(rs);
            }else{
                System.out.println("无法变换");
            }
    
    
        }
        //由于输入的字符串与魔板上字符的顺序不一致,所以需要对数据进行预处理,将后四位翻转
        private static String preProcess(String number){
            return number.substring(0,4)+number.substring(7,8)+number.substring(6,7)+number.substring(5,6)+number.substring(4,5);
        }
        //上下两行互换
        public static String fun_A(String number){
            String a = number.substring(4,8) + number.substring(0,4);
            return a;
        }
        //每行同时循环右移一格
        public static String fun_B(String number){
            String a = number.substring(3,4)+number.substring(0,3)+number.substring(7,8)+number.substring(4,7);
            return a;
        }
    
        //中间四个方块顺时针旋转一格
        public static String fun_C(String number){
            String a = number.substring(0,1)+number.substring(5,6)+number.substring(1,2)+number.substring(3,4)+
                    number.substring(4,5)+number.substring(6,7)+number.substring(2,3)+number.substring(7,8);
            return a;
        }
    
        private static int getA(String status,int i){
            int rs = 0;
            for(int k = i+1;k < status.length();k++){
                if(status.charAt(k) < status.charAt(i)){
                    rs++;
                }
            }
            return rs;
        }
    
    
        //计算当前状态的cantor序号
        public static int cantor(String status){
            int[] a = new int[8];
            int rs = 0;
            for(int i = 0, j = 7;i < status.length();i++,j--){
                a[j] = getA(status,i);
            }
            for(int i = 7;i >= 0;i--){
                rs += a[i]*hash[i];
            }
            return rs;
    
        }
    
    
        public static boolean matches(String a,String b){
            if(a.length() != b.length()) return false;
            if(a.equals(b)) return true;
            else  return false;
        }
    
    
        public static String bfs(String start,String end){
            //某个序列状态是否已被搜索过
            boolean[] visited = new boolean[40320];
            String[] ans = new String[40320];
            Queue<String> status = new Queue<String>();
            status.enqueue(start);
            while(!status.isEmpty()){
                String tmp = status.dequeue();
                if(matches(tmp,end)){
                    return ans[cantor(tmp)];
                }
                if(!visited[cantor(tmp)]){
                    if(ans[cantor(tmp)] == null) ans[cantor(tmp)] = "";
                    if(ans[cantor(tmp)] == "" || ans[cantor(tmp)].substring(ans[cantor(tmp)].length()-1,ans[cantor(tmp)].length()) != "A"){
                        String fun_A_tmp = fun_A(tmp);
                        status.enqueue(fun_A_tmp);
                        ans[cantor(fun_A_tmp)] = ans[cantor(tmp)] + "A";
                    }
                    if(ans[cantor(tmp)].length() < 3 ||ans[cantor(tmp)].substring(ans[cantor(tmp)].length()-3,ans[cantor(tmp)].length()) != "BBB"){
                        String fun_B_tmp = fun_B(tmp);
                        status.enqueue(fun_B_tmp);
                        ans[cantor(fun_B_tmp)] = ans[cantor(tmp)] + "B";
                    }
                    if(ans[cantor(tmp)].length() < 3 ||ans[cantor(tmp)].substring(ans[cantor(tmp)].length()-3,ans[cantor(tmp)].length()) != "CCC"){
                        String fun_C_tmp = fun_C(tmp);
                        status.enqueue(fun_C_tmp);
                        ans[cantor(fun_C_tmp)] = ans[cantor(tmp)] + "C";
                    }
                }
                visited[cantor(tmp)] = true;
    
    
            }
            return null;
    
        }
    
    }

    总结:将全排列问题抽象为状态的枚举,将魔板问题抽象为状态的迁移是很关键的。Cantor展开将某个状态映射为某个自然数,在查找以及计数问题中可以起到很大的作用。


    头一次认真写博文
    谢谢阅读,欢迎指正~
    若有同类问题希望能帮忙补充。

    展开全文
  • 作用: 1.知道一个序列的所有成员,可以很快得到这个序列的第k大序列(按字典序排序) 2.给定一个序列,很快可以算出所给序列的大小(按字典序排序),常用于状态压缩 将含有n个元素的序列转换成一个数字(字典序...

    作用:

    • 1.知道一个序列的所有成员,可以很快得到这个序列的第k大序列(按字典序排序)
    • 2.给定一个序列,很快可以算出所给序列的大小(按字典序排序),常用于状态压缩

    将含有n个元素的序列转换成一个数字(字典序大小)

    公式 $k = a_n * (n-1)! + a_{n-1} * (n-2)! + ... + a_2*1! + a_1 * 0!$

    对于$a_i$,代表当前元素在所有元素中是第$i$大的数字。(下标从0开始)

    例如:对于序列 5 3 2 4 1;

    $ k = 4 * 4! + 2 * 3! + 1 * 2! + 1 * 1! + 0 * 0! $

    第一个元素5对于序列5 3 2 4 1来说是第4大的数字。(下标从0开始)

    第二个元素3对于序列3 2 4 1来说是第2大的数字。

    第三个元素2对于序列2 4 1来说是第1大的数字。

    第四个元素4对于序列4 1来说是第1大的数字。

    第五个元素1对于序列1来说是第0大的数字。

    给定一个数字k,计算第k大的序列。

    由上一步可知,将一个数字k转换成一个序列。

    第一步求出(n-1)!阶乘的系数a,在从原序列中找对应数字(第a大的数字)。

    第二部对(n-1)!求余,用剩下的数求出(n-2)!阶乘的系数b,在剩下序列中找对应数字(第b大的数字)

    ...

    依次进行,即可求出原序列。

    转载于:https://www.cnblogs.com/aiterator/p/6675416.html

    展开全文
  • Cantor展开

    2013-11-14 20:03:00
    X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!...这就是康托展开。康托展开可用代码实现。 康托展开的应用实例: {1,2,3,4,...,n}表示1,2,3,...,n的排列 如 {1,2,3} 按从小到大排列一共6个。123 132 213 231 312...
  • 题意:八数码,但是转移的方式是转动,一共十二种...学了逆cantor展开cantor展开是一个变进制数,每位上是原序列对应位置上的逆序值。那么求逆时候,就先除最大的位权得到对应位置上的逆序值,根据逆序值可以知道...
  • 利用公式编程求出一个序列在全排列中的编号 X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0!
  • [知识点]Cantor展开

    2015-07-26 10:32:00
     例如,3 5 7 4 1 2 9 6 8 展开为 98884。因为X=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884.  排列的第一位是3,比3小的数有两个,以这样的数开始的排列有8!个,因此第一项为2*8! 排列的第二位是5,比...
  • G++是怎么做到空间换时间的啊。...预备知识:算法基础:康托展开与逆康托展开 代码如下: #include<queue> #include<string> #include<cstdio> using namespace std; const in...
  • 广度搜索很好想,主要难想的地方在hash判重,这里用到的是cantor展开判重复 基本思想是,从全排列组成的数字中,找出比他小的有数有多少 对于一个数字,从第一位看起,找他后面有多少个比这一位小的位,比如有...
  • 首先就是判重的问题,搜索的状态是九个数(含x),开个九重数组也不是不可以,但用cantor展开hash一下还是方便的。所谓cantor展开,就是对1..n的所有排列,唯一对应一个1..n!的值。 cantor展开解决互不相同的元素...
  • 参数int puzz[]为待展开之数的各位数字,如需展开2134,则puzz[4]={2,1,3,4}. int Can( string puzz) // psize puzz集合的大小 { int psize= puzz.size(); int ct = 0 ; for ( int i = 0 ; i 1 ; ...
  • Cantor 康拓展开

    2015-08-03 21:22:20
    const int PermSize = 10; long long factory[PermSize]={0,1,2,6,24,120,720,5040,40320,362880};...long long Cantor(string buf) { int i, j, counted; long long result = 0; for(i = 0; i < PermSiz
  • 康托(Cantor)展开

    2018-02-20 11:37:00
    1. 输入一个组合,输出在对应数字从小到大的全排列中的编号。 输入:35142 ,输出:68 1 #include <stdio.h> 2 #include <... 6 int F[10] = {1,1,2,6,24,120,720,5040,40320,3...
  • 康托(cantor展开

    2013-04-12 16:32:00
    康托展开的公式 把一个整数X展开成如下形式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0! 其中,a为整数,并且0<=a[i]<i(1<=i<=n) 康托展开的应用实例 {1,2,3,4,...,n}...
  • 康托展开 定义 对于n位数的某个排列s[0,n-1],有 X=a[n]∗(n−1)!+a[n−1]∗(n−2)!+...+a[i]∗(i−1)!+...+a[1]∗0! X 为 s 在整个全排列中的位置-1 a[i] 表示在i位后面出现的小于s[i]的数 的个数 解释 通过...
  • 康托展开(Cantor expansion)及逆康托展开 康托展开 康托展开的定义 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此...
  • 康托展开是一个全排列到一个自然数的双射。所以可逆。 康托展开:给定一个数n,和一个n位的全排列,求出这个排列是第几位X 逆康托展开:给定一个数n,和这个排列占第几位X, 求出这个排列 这里X(注意第一个排列...
  • 康托展开 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的名次,因此是可逆的。 公式: X = A[0] * (n-1)! + A[1] * (n-2)! + … +...
  •  将一个整数X展开为如下形式:  X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0! (其中,a为整数,并且0 全排列的编码:  {1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道...
  • 求解Cantor集上波动方程和扩散方程的局部分式级数展开法。

空空如也

空空如也

1 2 3 4 5 6
收藏数 102
精华内容 40
关键字:

cantor展开