字符串排列与组合

一、字符串的排列

给定一个字符串,如何求出字符串的所有排列。

解题思路:字符串的排列可以拆分成,第一个字符和后面的字符进行组合而成,只需要变换第一个字符,然后递归求后面的字符的排列即可,等到后面的字符为空的时候就得到一种字符的排列,下面是代码实现:

// str 要排列的字符串
// pBegin 待排列的字符串的起始位置,递归用
void Permutation(char *str, char *pBegin)
{
    // 如果待排列的字符串为空,即起始位置为'\0',则得到一种排列,打印
	if (*pBegin == '\0')
		printf("%s\n", str);
	else // 否则遍历字符串,分别和第一个字符进行换位置,然后递归排列后面的字符
	{
		for (char *pCh = pBegin; *pCh != '\0'; ++pCh)
		{
			char temp = *pCh;
			*pCh = *pBegin;
			*pBegin = temp;

			Permutation(str, pBegin + 1);

            // 排列完成后还原位置
			temp = *pCh;
			*pCh = *pBegin;
			*pBegin = temp;
		}
	}
}

// 外部函数
void Permutation(char *str)
{
	if (str == NULL)
		return;

	Permutation(str, str);
}

二、字符串的组合

如何求字符串的所有组合,组合和排列不同,例如:"abc"的组合有"a"、“b”、“c”、“ab”、 “ac”、“bc”和“abc”。

解题思路:对于一个长度为n的字符,它的组合长度有1位、2位、3位...n位,可以用循环分别求1-n位的组合,对于m位的组合可以拆分成取第一位,然后从后面的n-1位取m-1位组成一个组合,或者不取第一位,然后从后面的n-1位取m位组成一个组合,形成一个递归算法,代码如下:

// 递归求iNum位的所有组合
// pStr 要求组合的字符串
// iNum 组合的位数
// result 保存组合
void Combination(char *pStr, int iNum, std::vector<char> &result)
{
    // 如果字符串为空,或者要求组合的位数不为0且字符串为空,则不可能生成组合
	if (pStr == NULL || (iNum != 0 && *pStr == '\0'))
		return;

    // 如果要求组合的位数为0,表示已生成组合,则打印组合
	if (iNum == 0)
	{
		std::vector<char>::iterator it;
		for (it = result.begin(); it != result.end(); ++it)
		{
			printf("%c", *it);
		}
		printf("\n");
	}
	else 
	{
        // 否则取第一个字符作为组合第一位,从剩下n-1位,取iNum - 1个字符得到组合
		result.push_back(*pStr);
		Combination(pStr + 1, iNum - 1, result);

        // 另一种情况,不取第一位,从剩下的n-1位,取iNum个字符得到组合
		result.pop_back();
		Combination(pStr + 1, iNum, result);
	}
}

// 外部函数,分别求1-n位的所有组合
void Combination(char * str)
{
	int n = strlen(str);
	std::vector<char> result;
	for (int i = 1; i <= n; i++)
	{
		Combination(str, i, result);
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vfdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值