字符串排列递归和非递归实现

求一个全排列函数:p([1,2,3])输出:[123][132][213][231][321][323]
1、递归的方法:

依次把每个字符交换到第一个位置,后面的字符做同样的递归过程。

void Permutation(char *str)
{
	void PSolution(char *str, int begin, int end);
	int Length;
	if(str == NULL || (Length = strlen(str)) == 0)
		return;
	PSolution(str, 0, Length);
}

void PSolution(char *str, int begin, int end)
{
	void swap(char *, char *);
	if(begin == end-1)
	{
		cout<<str<<endl;
		return;
	}
	for(int i = begin; i < end; ++i)
	{
		swap(str+i, str + begin);
		PSolution(str, begin+1, end);
		swap(str+i, str+ begin);
	}

}

void swap(char *a, char *b)
{
	char c;
	c = *a;
	*a = *b;
	*b = c;
}

2、字典序的方法:

1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}

2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)

3)pj,pk

4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。

void Reverse(char *p, char *q)
{
	char temp;
	while(p < q)
	{
		temp = *p;
		*p = *q;
		*q = temp;
		p++;
		q--;
	}
}
void swap(char *p, char *q)
{
	char temp;
	temp = *p;
	*p = *q;
	*q = temp;
}
int Mult(int i)
{
	int sum = 1;
	while(i)
	{
		sum *= i;
		i--;
	}
	return sum;
}
void permutation2(char *p)
{
	int i = strlen(p);
	int cout = Mult(i);
	int j = 0;
	int pLeft, pRight;
	int RMin;
	printf("%s\n", p);
	while(--cout)
	{
		for(j = i-2; j >= 0 && p[j] > p[j+1]; j--)
			;
        pLeft = j;
		RMin = *(p+pLeft+1);
		for(j = pLeft+1; j <= i-1; j++)
		{
			if((*(p+j) > *(p+pLeft)) && (*(p+j) <= RMin))
			{
				RMin = *(p+j);
				pRight = j;
			}
		}
		swap(p+pLeft, p + pRight);
		Reverse(p+pLeft+1, p+i-1);
		printf("%s\n", p);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值