全排列问题
关于一组数的全排列,我的思路是:我先定义一个相当于一个栈的数组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");
}