2013年腾讯笔试题:n个元素顺序入栈,出栈顺序有多少种?

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
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值