康托展开的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\n", 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\n", arr);
}
return 0;
}