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

  可以用于求排列的第几大。如要求{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[n]>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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值