上一次学习栈我们学习了关于栈的基本知识。这次,我们来讲一讲关于栈的应用。
栈的应用
1、进制转换
十进制数与其他d进制数的转换是不同进制计算的基本要求,解决问题的算法很多,在这里我提到一种算法:
n
=
(
n
/
d
)
∗
d
+
n
/
/
d
n=(n/d)*d+n//d
n=(n/d)∗d+n//d (//为求余,d为进制数)
假设d=8,n=1348,
n n n | ( n / 8 ) ∗ 8 (n/8)*8 (n/8)∗8 | n / / 8 n//8 n//8 |
---|---|---|
1348 | 168 | 4 |
168 | 21 | 0 |
21 | 2 | 5 |
2 | 0 | 2 |
最后一列倒着看,
(
2504
)
8
=
(
1348
)
10
(2504)_8 =(1348)_{10}
(2504)8=(1348)10
这个倒过来便成了栈的应用。
程序范例:
#include<iostream>
using namespace std;
int a[101],n,d;
int main()
{
int i;
cin>>n>>d; //没有加字符功能,只适用于10进制以下
do
{
a[++i]=n%d;
n=n/d;
}
while(n!=0);
for(int j=i;j>=1;j--) cout<<a[j];
return 0;
}
2、最经典的火车列车调度问题。
很简单这就是一个栈的模型,直接硬掰就可以了
不过,这里有两个问题,如果进站的序列为123,出站可能是什么序列?如果进栈是654321,问能否得到624531的序列和216534的序列?
程序太简单了,希望读者自己编写。
3、括号匹配问题
在我们题库里有好多道括号匹配,当时标注的是递归,现在想想,根本不用递归嘛,直接压栈,一点时间复杂度都没有。
算法小分析
算法就是碰到前括号就压栈,碰到后括号就退栈,一匹配,便知真假。
超级简单,是不是?
范例程序: (如果程序错误,请留言,谢谢)
#include<iostream>
#include<cstdio>
using namespace std;
char a[10000001];
int z[10000001];
int zz=0;
int main()
{
gets(a);
int i=0;
while(a[i]!=0)
{
i++;
if(a[i]=='(')
{
zz++;
z[zz]=1;
}
else
{
if(z[zz]!=')')
{
cout<<"error";
return 0;
}
else continue;
}
}
cout<<"right";
return 0;
}
4、逆波兰表达式(或后缀表达式)的值
求一个后缀表达式(字符创)的值,只有0~9,+,-,*,/这几个运算符号,直接运算整数结果;
又是一个特别简单的题,是不?
算法小分析
我们来观察一下
6.8.4.2+*-/
(点是空格)
遇到数直接压栈,遇到符号直接计算弹出。简单666
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[101];
char c[101];
int cz()
{
int i=0,zz=0,x,y;
while(i<=strlen(c)-2)
{
switch(c[i])
{
case '+':a[--zz]+=a[zz+1];break;
case '-':a[--zz]-=a[zz+1];break;
case '*':a[--zz]*=a[zz+1];break;
case '/':a[--zz]/=a[zz+1];break;
default:x=0;while(c[i]!=' ') x=x*10+c[i++]-48;a[++zz]=x;break;
}
i++;
}
return a[++zz];
}
int main()
{
get(s);
cout<<cz();
return 0;
}
今天的例题就到这里结束了!加油吧各位大佬们