给定入栈顺序,求解出栈顺序?

qiuxuezhizi 2008-04-06 02:48:05
给定入栈顺序,出栈可随时进行,这样除了穷举法,有没有什么规律可以遵循,或者是相关的算法。

例如:
入栈顺序是abc
则出栈顺序可以是:abc,abc,bca,bac,cba.一共是5种出栈顺序,就是没有cab这种。
有没有什么规律可言呢?
...全文
3453 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengcman 2009-05-07
  • 打赏
  • 举报
回复
浙大Acm习题网上的一道题目。。。
yezeguo 2009-05-07
  • 打赏
  • 举报
回复
0分贴?
hengxin196 2009-05-06
  • 打赏
  • 举报
回复
你Y的不实在啊 等于没说[Quote=引用 15 楼 jing_xin 的回复:]
出栈,入栈规律即:1.出的个数必须小于入的个数。2.所有出的个数最终与入的个数相等。
[/Quote]
JulianSeaver 2009-03-19
  • 打赏
  • 举报
回复
如果只要给出有多少种. 13楼才是正解. 这个题在CSDN上有太多回了.
iwantnon 2009-03-11
  • 打赏
  • 举报
回复
根据13楼结论2写的判断
#include <iostream>
#include <vector>
using namespace std;
#include "func.h"
bool ju(const vector<int>&vec)
{
int n=(int)vec.size ();
int max=0;
for(int i=0;i<=n-1;i++)
{
if(vec[i]<max)continue;
else if(vec[i]>max)
{//设vec[i]后面第一个小于max的数为p,则区间(vec[i],p)上小于vec[i]的数应为降序
vector<int> pipe(2,vec[i]);//长度为2的管道
for(int j=i;j<=n-1;j++)
{
if(vec[j]<max)break;
if(vec[j]<vec[i])
{
pipe[0]=pipe[1];
pipe[1]=vec[j];
if(pipe[0]>pipe[1])continue;
else if(pipe[0]<pipe[1])
{
return false;
}
}
}
max=vec[i];
}
}
return true;
}
main()
{
vector<int> vec1,vec2;
init(vec1,6,
4,2,5,3,1,6);
init(vec2,6,
4,3,5,2,1,6);
cout<<ju(vec1)<<endl;
cout<<ju(vec2)<<endl;
}

输出结果:
0
1
即4,2,5,3,1,6不是出栈序列。
4,3,5,2,1,6是出栈序列。
kon3155 2009-03-10
  • 打赏
  • 举报
回复
http://www.myfirm.cn/News/dotNetGUI/2007062905490837.html
iwantnon 2009-03-10
  • 打赏
  • 举报
回复
有数学公式
有算法
有。。。
总之关于这个问题,什么都有。
ex_dijkstra 2009-03-10
  • 打赏
  • 举报
回复
牲口
iwantnon 2009-03-10
  • 打赏
  • 举报
回复
列举出栈序列最容易:
#include <iostream>
#include <vector>
using namespace std;
#include "func.h"
void finn(const int n,int cur,vector<int>&stac,vector<int>&outL,int&count)
{
if((int)outL.size ()==n)//终点
{
print(outL);
count++;
}
if(cur!=n+1)//入栈
{
//操作
stac.push_back(cur);
//进入下层
finn(n,cur+1,stac,outL,count);
//恢复
stac.pop_back ();
}
if(!stac.empty())//出栈
{
//留底
int temp=stac[(int)stac.size ()-1];
//操作
outL.push_back (temp);
stac.pop_back ();
//进入下层
finn(n,cur,stac,outL,count);
//恢复
outL.pop_back ();
stac.push_back (temp);
}
}
int f(const int n)
{
vector<int> stac;
vector<int> outL;
int count=0;
finn(n,1,stac,outL,count);
return count;
}
main()
{
int n;
cout<<"n=";
cin>>n;
cout<<"共"<<f(n)<<"个"<<endl;
}

运行结果:
n=4
4 3 2 1
3 4 2 1
3 2 4 1
3 2 1 4
2 4 3 1
2 3 4 1
2 3 1 4
2 1 4 3
2 1 3 4
1 4 3 2
1 3 4 2
1 3 2 4
1 2 4 3
1 2 3 4
共14个
iwantnon 2009-03-10
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jing_xin 的回复:]
出栈,入栈规律即:1.出的个数必须小于入的个数。2.所有出的个数最终与入的个数相等。
[/Quote]
完全正确,这也正是卡塔兰数的几何意义,13楼的结论1就是用这个证明的。
这个规律也可用于13楼所说的程序3:列举I(n)的所有出栈序列。会是一个高效算法。
fenix124 2009-03-10
  • 打赏
  • 举报
回复
我靠,搞了半天忽然没有看见问题在哪儿。
楼上那儿学到点东西
静_心 2009-03-10
  • 打赏
  • 举报
回复
出栈,入栈规律即:1.出的个数必须小于入的个数。2.所有出的个数最终与入的个数相等。
静_心 2009-03-10
  • 打赏
  • 举报
回复
出栈,入栈规律即:1.出的个数必须小于入的个数。2.所有出的个数最终与入的个数相等。
iwantnon 2009-03-10
  • 打赏
  • 举报
回复
先说两条数学结论:
设入栈序列为I(n):1,2,...,n
1,I(n)有C(2n,n)-C(2n,n-1)个出栈序列。
2,L(n)是I(n)的一个出栈序列当且仅当:对于L(n)的任意一位数M,其后面比它小的数降序排列。
注:[1],结论1是数《数据结构》课本上的原话,所以不会有错,另外根据卡塔兰数的几何意义,也容易证明。
[2],结论2是我自己观察的,自认为应该是对的。举个例子如下:
判断序列L(6):4,3,5,2,1,6是否为I(6)的出栈序列。
解:4后面比4小的数3,2,1是降序列;3后面比3小的数2,1是降序排列;5后面比5小的数2,1是降序排列;2后面比2小的数φ是降序排列;1后面比1小的数φ降序排列;6后面比6小的数φ是降序排列。所以L(6)是I(6)的一个出栈序列。
--
接下来就是程序:
1,判定函数bool ju(L):输入序列L判断其是否为I的出栈序列。用结论2的思路即可,可以优化。
2,过程复原函数Ls proc(L):输入I的出栈序列L,输出完整的出入栈过程,如果输入的L不是I的出栈序列,给出提示,因此proc也具有判定功能。
3,列举I(n)的所有出栈序列,大概11楼给的算法就是做这件事的吧。
有时间我做做试试。
iwantnon 2009-03-10
  • 打赏
  • 举报
回复
to楼上:
代码太抽象,能不能简要说一下算法思路,我好弄清楚这个与我知道的那个方法是否相同。
meiZiNick 2008-04-30
  • 打赏
  • 举报
回复
没遇到过这种情况.
jinwei1984 2008-04-09
  • 打赏
  • 举报
回复
mark
medie2005 2008-04-07
  • 打赏
  • 举报
回复
本来想答的,但是,一看这是0分贴,就算了吧
feixiangshunjian 2008-04-07
  • 打赏
  • 举报
回复
好像是进栈了只能选择不出来,而不能往后倒退。
老师说就像是两辆火车相遇,中间有个中转站一样。
rushman 2008-04-06
  • 打赏
  • 举报
回复
把功夫用在优化“穷举”算法上比较现实。
加载更多回复(3)

33,014

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧