栈的应用
栈的应用之一:括号匹配
括号匹配问题是考察栈的常考问题。括号匹配充分应用了栈的后进先出的原理。举例来说,比如字符串(a*(c+b)-d)中,第一个位置和第四个位置有左括号,第八个位置和第11个位置有右括号。并且它们相互匹配。在比如(a+b))(,在这个串中,我们应如何判断哪个匹配呢,这就得依靠栈。我们建立一个int栈,可以将左括号的位置压入栈中,然后遍历字符串,如果发现右括号就将栈顶元素出栈,就可以匹配了。等遍历结束。如果栈中还有括号说明没有匹配。。那么talk is easy,show me the code;
#include<iostream>
#include<string.h>
#include<stdio.h>
#include"LITSTK.h"
using namespace std;
const int maxlength=100;
void print(char *expression)
{
Seqstack<int> s(maxlength);
int j=0,length=strlen(expression);
for(int i=1;i<=length;i++)
{
if(expression[i-1]=='(')
{
s.Push(i);
}
else if(expression[i-1]==')')
{
if(s.Pop(j)==true)
{
cout<<j<<"与"<<i<<"匹配"<<endl;
}
else
{ cout<<"没有与第"<<i<<"个右括号匹配的左括号!"<<endl;}
}
}
while(s.Isempty()==false)
{
s.Pop(j);
cout<<"没有与第"<<j<<"个左括号相匹配的右括号!"<<endl;
}
}
int main()
{
char a[100];
while(gets(a))
{
print(a);
}
}
栈的应用之二:表达式计算
在计算机中计算表达式是通过栈来进行的。在了解它的原理之前我们先回顾表达式的概念。
表达式是由操作数,操作符,分界符组成的。通常,分为算术表达式,逻辑表达式,关系表达式等等,今天着重算术表达式。那么算术表达式分三种:
1.中缀表达式
2.后缀表达式
3.前缀表达式
什么区别呢?所说的某缀就是操作符的位置,如果操作符在操作数前称前缀。依次类比。
我们日常使用的都是中缀表达式。但是它在计算中必须明确运算顺序。也就是优先级。所以对于计算机来说,不太方便。我们通常在计算机中用后缀表达式。这样我们只需一个栈来保存操作数就行了。那么具体怎么做呢。
我们分析一下。要想计算它的值,就必然明确两个操作数,和操作符。我们定义一个calculator类。它包括一个栈定义,一个将操作数压入栈中的函数,还有退出两个操作数的函数。还有计算函数。好了,具体代码请看:
#include<math.h>
#include<iostream>
#include"LITSTK.h"
class calculator{
public:
calculator(int sz):s(sz){}
void Run();
void Clear();
private:
Seqstack<double> s;
void addoperand(double value);
bool get2oprands(double &left,double &right);
void dooperator(char op);
};
void calculator::dooperator(char op)
{
double left,right,value;int result;
result=get2oprands(left,right);
if(result==true)
{
switch(op){
case '+': value=left+right;s.Push(value);break;
case '-': value=left-right;s.Push(value);break;
case '*': value=left*right;s.Push(value);break;
case '/': if(right==0.0){
cerr<<"error"<<endl;
Clear();
}
else {value=left/right;s.Push(value);break;}
break;
}
}
else Clear();
};
bool calculator::get2oprands(double &left,double &right)
{
if(s.Isempty()==true)
{
cerr<<"缺省右操作数"<<endl;
return false;
}
s.Pop(right);
if(s.Isempty()==true)
{
cerr<<"缺省左操作数"<<endl;
return false;
}
s.Pop(left);
return true;
};
void calculator::addoperand(double value)
{
s.Push(value);
};
void calculator::Run()
{
char ch;double newoperand;
while(cin>>ch,ch!='#')
{
switch(ch)
{
case'+': case'-': case'*': case'/':
dooperator(ch);break;
default:cin.putback(ch);
cin>>newoperand;
addoperand(newoperand);
}
}
};
void calculator::Clear()
{
s.makeempty();
};
int main()
{
calculator cal(10);
cal.Run();
}