问题:
实现全排列
输出长这样:
111,112,113,121,122,123,131,132,133,211,212,213,221,222,223,231,232,233,311,312,313,321,322,323,331,332,333,
Process exited after 0.05746 seconds with return value 0 请按任意键继续…
递归(我的视角)
递归实现的代码框架(伪代码)
//s相当于当前的层数 e相当于所有的层数 //list初始化就是一棵空的队列,不断的添加节点和删除节点 void perm(int
list[], int s, int e)) {
int i;
if(s < e) //注意:这里不应该用while 因为每一层只需要调用节点数个递归就行了,也就是说每一层只需要负责广度,深度由递归的调用去是实现
{for(i = s; i <= e; i++) { add(set,i) perm(list, s + 1, e); remove(set,i) //add和move都是为了 保护现场,为了下一次平行节点的重新展开作准备 }
//s++; //没必要 ,s++的工作其实就是纵向深入,这个工作由递归实现
} if(s>=e) { printf(set)}
}
完整的代码(自己随便瞎写的 (^_^))
java实现
public class Pailie {
final static int ee= 3; //实现123的全排列
void add(int[]o, int i,int s)
{
o[s] = i;
}
void remove(int []o, int i,int s)
{
o[s] = 0;
}
void perm(int []list, int s, int e)
{
// printf("(s=%d)", s); 调试用
if(s >e)
{
//把这个排列组合输出出来
for(int ii = 0; ii <= e; ii++)
{
System.out.printf("%d", list[ii]);
}
System.out.printf((s == ee) ?",":"");
}
else //纵深
{
for(int i = 1; i <= e+1; i++)
{
add(list, i,s);
perm(list, s + 1, e);
remove(list, i,s);
}
}
}
public static void main(String argv[])
{
int list[]=new int[ee];
int s=0,e=ee-1;
Pailie a=new Pailie();
a.perm(list,s,e);
}
}
C/C++实现
#include <stdio.h>
#define ee 3 //实现123的全排列 实现1-ee的全排列
void add(int * o, int i,int s)
{
o[s] = i;
}
void remove(int * o, int i,int s)
{
o[s] = 0;
}
void perm(int *list, int s, int e)
{
// printf("(s=%d)", s); 调试用
if(s >e)
{
//把这个排列组合输出出来
for(int ii = 0; ii <= e; ii++)
{
printf("%d", list[ii]);
}
(s == ee) ? printf(",") : printf("");
}
else //纵深
{
for(int i = 1; i <= e+1; i++)
{
add(list, i,s);
perm(list, s + 1, e);
remove(list, i,s);
}
}
}
int main()
{
int list[ee]={0};
int s=0,e=ee-1;
perm(list,s,e);
return 0;
}
参考文献
https://www.cnblogs.com/autosar/archive/2012/04/08/2437799.html
补充
1实现任意n位数的全排列
#include <stdio.h>
#define ee 3 //实现三位数的全排列
void add(char * o, char i,int s)
{
o[s] = i;
}
void remove(char * o, char i,int s)
{
o[s] = 0;
}
void perm(char *list, char s, int e)
{
// printf("(s=%d)", s); 调试用
if(s >e)
{
//把这个排列组合输出出来
for(int ii = 0; ii <= e; ii++)
{
printf("%c", list[ii]);
}
(s == e+1) ? printf(",") : printf("");
}
else //纵深
{
for(int i = 0; i <2; i++)
{
if(i==0)
{
add(list, '(',s);
perm(list, s + 1, e);
remove(list, '(',s);
}else
{
add(list, ')',s);
perm(list, s + 1, e);
remove(list, ')',s);
}
}
}
}
int main()
{
char list[ee]={0};
int s=0,e=ee*2-1;
perm(list,s,e);
return 0;
}
输出
((((((,(((((),(((()(,(((()),((()((,((()(),((())(,((())),(()(((,(()((),(()()(,(()()),(())((,(())(),(()))(,(()))),()((((,()(((),()(()(,()(()),()()((,()()(),()())(,()())),())(((,())((),())()(,())()),()))((,()))(),())))(,())))),)(((((,)((((),)((()(,)((()),)(()((,)(()(),)(())(,)(())),)()(((,)()((),)()()(,)()()),)())((,)())(),)()))(,)()))),))((((,))(((),))(()(,))(()),))()((,))()(),))())(,))())),)))(((,)))((),)))()(,)))()),))))((,))))(),)))))(,)))))),
Process exited after 0.1733 seconds with return value 0 请按任意键继续…
2括号配对问题
//(基于上面的排列实现的,程序写的有点乱,凑合看吧,,ԾㅂԾ,,)
#include <stdio.h>
#define ee 3 //实现三位数的全排列
int leftsum=0;
int rightsum=0;
void add(char * o, char i,int s)
{
o[s] = i;
}
void remove(char * o, char i,int s)
{
o[s] = 0;
}
void perm(char *list, char s, int e)
{
// printf("(s=%d)", s); 调试用
if(leftsum>=rightsum&&leftsum<=3&&rightsum<=3) //只有在左括号数 大于右括号数的前提下 才继续进行
{
if(s >e)
{
//把这个排列组合输出出来
for(int ii = 0; ii <= e; ii++)
{
printf("%c", list[ii]);
}
(s == e+1) ? printf(",") : printf("");
}
else //纵深
{
for(int i = 0; i <2; i++)
{
if(i==0)
{
add(list, '(',s);
leftsum++;
perm(list, s + 1, e);
remove(list, '(',s);
leftsum--;
}else
{
add(list, ')',s);
rightsum++;
perm(list, s + 1, e);
remove(list, ')',s);
rightsum--;
}
}
}
}
}
int main()
{
char list[ee]={0};
int s=0,e=ee*2-1;
perm(list,s,e);
return 0;
}
输出
((())),(()()),(())(),()(()),()()(),
Process exited after 0.1185 seconds with return value 0 请按任意键继续…