n个元素顺序入栈,出栈顺序有多少种?
转者注 这个的结果有数学公式的 是C(n,2n)-C(n-1,2n),至于公式怎么来,必须将问题转化为数学问题 “卡塔兰数”(Catalan).程序员的做法是用递归,要想写出效率高的程序,就得用这个数学问题推导出来的 公式 .
转载自 http://blog.163.com/hbkjdx205@126/blog/static/315781012007512101622112/
第一次遇到这个题目,还是一年前在新东方的一次笔试中,那时还是一个填空题!我晕,我咋知道,好像课堂上没有见过,或许我学数据结构等课程时,根本就没有学透的原因吧!反正当时没有做出来。以下这两段程序都测试通过,代码是没有问题的,可以直接运行,若出错一般都是环境或配置造成。C版(网友提供):在visual studio .net 2003上测试通过。
#include "stdafx.h"
#include <string.h>
#include <stdio.h>
char str[20];
int num,kinds; //num为输入字符个数,kinds为输出情况种类
char outputs[20]; //按出栈顺序存储输出字符
void f ( int ins_num, int outs_num, char *ins)//栈内元素个数, 出栈元素个数
{
char ins_c[20];
strncpy( ins_c, ins, ins_num);
if (outs_num==num)
{
kinds++;
for(int i=0; i<num; i++)
putchar(outputs[i]);
printf(" 第%d种",kinds);
printf("\n");
}
else
{
if (ins_num>0) //出栈衍生
{
outputs [outs_num] = ins_c [ ins_num-1];
f ( ins_num-1, outs_num+1,ins_c);
}
if ( num - ins_num - outs_num) //入栈衍生
{
ins_c [ins_num] = str [ins_num + outs_num];
f ( ins_num+1, outs_num, ins_c);
}
}
}
void main()
{
printf("请输入入栈序列");
scanf("%s",str);
num = strlen (str);
char *p;
f ( 0, 0, p);
printf("共有%d种输出方式",kinds);
system("pause");
}
java版(根据C版,修改而成):在jdk1.4.2上eclipse3.2中测试通过。
public class Test2
{
int sum=4,insNO=0,outNO=0,count=0;
int srcArray[]={1,2,3,4};
int outArray[]=new int[sum];
public static void main(String[] args)
{
Test2 test = new Test2();
test.f(test.insNO,test.outNO,new int[test.sum]);
}
void f(int insNO,int outNO,int[] ins)
{
int insArray[]=new int[this.sum];
System.arraycopy(ins,0, insArray,0,insNO);
if(outNO==this.sum)
{
print(this.outArray);
}else
{
if(insNO>0)
{
this.outArray[outNO] = ins[insNO-1];// 出栈
f(insNO-1,outNO+1,ins);
}
if((this.sum-insNO-outNO)>0)
{
insArray[insNO] = srcArray[insNO+outNO];// 入栈
f(insNO+1,outNO,insArray);
}
}
}
void print(int[] AR)
{
for (int i = 0; i < sum; i++)
{
System.out.print(AR[i]);
}
System.out.println(" 第"+(++count)+"种");
}
}
测试结果:设F(n)=出栈种数。
F(1)=1
F(2)=2
F(3)=5
F(4)=14
F(5)=42
F(6)=132
F(7)=429
F(8)=1430
F(9)=4862
F(10)=16796