康托展开的wiki介绍
申明:
1.用c语言实现。
2.for中的i,j定义适用于c99标准,gcc编译要添加-std=c99选项。或者将i,j的定义放到for之前的外部作用域。
3.逆运算使用了c99标准的VLA,即变长数组,只能用于局部作用域,且声明时不能初始化;也可以不用VLA,使用malloc等从堆上分配空间来使用。
4.n为序列长度,即元素个数(从1开始);arr为对应的序列,用字符数组表示;value为康托展开的值,即序号。
康托展开
int cantor(int n, char arr[]) { int value = 0; for(int i = 0; i < n; i++) { int a = 0; for(int j = i + 1; j < n; j++) if(arr[i] > arr[j]) a++; else if(arr[i] == arr[j]) return -1; value += a * get_factorial(n - i -1); } return value; }
int uncantor(int n, int value, char arr[]) { if(value > get_factorial(n) - 1) return -1; int temp[n]; for(int i = 0; i < n; i++) temp[i] = 0; for(int i = 0; i < n; i++) { int num = value / get_factorial(n - i - 1); for(int j = 0, k = num; k >= 0 && j < n; j++) if(temp[j] == 1) num++; else k--; arr[i] = '1' + num; temp[num] = 1; value %= get_factorial(n - i -1); } return 0; }
int get_factorial(int n) { if(n < 0) return 0; else if(n == 0) return 1; else return n * get_factorial(n - 1); }
#include <stdio.h> #include <string.h> int get_factorial(int n); int cantor(int n, char arr[]); void uncantor(int n, int value, char arr[]); int main(void) { printf("please select cantor(0) or uncantor(1):"); char c = NULL; if((c = getchar()) == '0') { char arr[10] = {0}, len = 0; printf("please input the arr(the length between 1~9):"); scanf("%s", arr); len = strlen(arr); if(len < 10) printf("the value is:%d ", cantor(len, arr)); } else if(c == '1') { int n, value; printf("please input n and value:"); scanf("%d%d", &n, &value); char arr[n + 1]; for(int i = 0; i < n + 1; i++) arr[i] = 0; uncantor(n, value, arr); printf("the arr is:%s ", arr); } return 0; }