您的位置:首页 > 其它

康拓展开和(逆康拓展开)

2013-01-12 17:38 225 查看

可以用于求排列的第几大。如要求{1,3,2}在排列{1,2,3}中是第几大时可以用康拓展开来求

这个博客里面讲得很清楚:

1-2-3的博客

#include<iostream>
#include<string>
using namespace std;

long fac[13];
int an(const string & s,int n)	//求下标为n的字符在子数组中第几大,从0开始数
{
int result = 0,i;
for (i=n+1;i<s.length();i++)
if (s
>s[i])
result++;
return result;
}
void Factorial()	//计算阶乘
{
fac[0] = 1;
int i;
for (i=1;i<13;i++)
fac[i] =fac[i-1]*i;
}
long X(const string & s)//求康托展开的X值
{
long result = 0;
int len = s.length();
int i;
for (i=0;i<len;i++)
{
result += an(s,i)*fac[len-i-1];
}
return result;
}
/*测试*/
int main()
{
string s = "ABC";
string s1 = "ACB";
Factorial();
cout<<X(s)<<endl;
cout<<X(s1)<<endl;
return 0;
}


逆康拓展开,用于求第几个排列

/*逆康拓展开*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

long fac[13];

void Factorial()	//计算阶乘
{
fac[0] = 1;
int i;
for (i=1;i<13;i++)
fac[i] =fac[i-1]*i;
}

int Ai(int an,int n,char sub[])//用于求第an大的字符
{
int r=-1,i;
for (i=0;i<n;i++)
{
if (sub[i]!='\0')
r++;
if (r==an)
return i;
}
}

/*s用于存放原始的排列(如{1,2,3}),m为所需求的第几个排列(从0开始)*/
char * Permutation(char s[],int m)
{
char *sub = new char[strlen(s)];	//用于标记哪个字符有用过或没用过
char *result = new char[strlen(s)];	//用于存放所求排列结果
strcpy(sub,s);
int i,j;
for (j=0,i=strlen(s)-1;i>=0;i--,j++)
{
int an = Ai(m/fac[i],strlen(s),sub);
result[j] = sub[an];
m = m%fac[i];
sub[an] = '\0';	//删去,表示已经用了
}
return result;
}

/*测试*/
int main()
{
Factorial();
char s[] = "abcdef";
char *c = Permutation(s,1);
int i;
for (i=0;i<strlen(s);i++)
putchar(c[i]);
putchar('\n');
free(c);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: