全排列问题

本文介绍了一种通过递归实现的全排列算法,并给出了详细的代码示例。该算法能够处理包含重复元素的情况,通过使用栈来存储临时排列结果,并利用链表来收集最终的不重复全排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全排列问题

 

  关于一组数的全排列,我的思路是:我先定义一个相当于一个栈的数组char *tempStr = new char[strlen(s)],这个数组将得到所有临时的排列结果,包括了相同的情况。同时我还定义了一个结果链表list<char*> resu,保存不重复出现的结果。

        然后使用递归不断将输入的字符串比如“122”从0号位置元素开始依次将字符赋值给tempStr(当然也是从0号位置开始接收),而传入下一个递归函数的字符串去掉了之前用去的字符,当传入的字符串为0时即出递归,这时已经填充满整个tempStr。再将tempStr与之前存入list的字符串相比较,若有相同项则不将这个字符串加入到链表中。下面是得到有相同项的全排列函数:

void solve(const char *s, int i, char* tempStr, int n)
{
	if(i < 1)
	{			//tempStr填补完全,经判断后将结果放入list中
		push(tempStr, n);
		return;
	}	

	char* next = new char[i - 1];//存放未添加的元素
	for(int j = 0; j < i; j++)
	{							//tempStr的填充由排列字符的0号位置开始一直到末端
		for(int k = 0; k < i; k++)
		{						//将未添加进tempStr的元素放入next中
			if(k == j)
				continue;
			else
				*(next++) = *(s + k);//依次赋值
		}
		next -= i - 1;			//next的地址返回到赋值前
		tempStr[n - i] = s[j];//填充tempStr
		solve(next, i - 1, tempStr, n);
	}
}


接着是得到无重复项结果的函数:

void push(char* s, int n)
{
	char *str = new char[n];//定义一个字符指针,将tempStr的值放入str中。
							//若直接放入tempStr则该值改变后,resu中凡是tempStr的赋值都一样
	strcpy(str, s);
	list<char*>::iterator it = resu.begin();
	while(it != resu.end())
	{
		if(!strcmp(*(it++), str))//若与前面结点有相同项则返回
			return;
	}
	resu.push_back(str);
}


附带输出结果函数和主函数:

#include <iostream>
using namespace std;
#include <list>
#include <string.h>


list<char*> resu;//存放结果的链表
void print_resu()
{//打印链表结果
	if(resu.empty())
		return;				//若链表为空则返回
	list<char*>::iterator it = resu.begin();
	while(it != resu.end())
	{
		cout << *(it++) << endl;
	}
}



 

void main()
{
	char *s = "122";
	char *tempStr = new char[strlen(s)];//存储全部排列的缓冲数组
	solve(s, strlen(s), tempStr, strlen(s));//全排列函数
	print_resu();//打印结果

	resu.clear();
	delete s;
	delete tempStr;
	system("pause");
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值