1. 逆波兰表达式算法简介
将一个普通的中序表达式转换为逆波兰表达式的一般算法是:
(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“@”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优先级低于当前运算符,将该字符入栈。
(5)重复上述操作(3)-(4)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
2. 程序化算法流程:
1、建立运算符栈stackOperator用于运算符的存储,压入’@’。
2、预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号) 。
3、顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接输出该数字;如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。
4、若当前运算符为’(‘,直接入栈;若为’)’,出栈并顺序输出运算符直到遇到第一个’(‘,遇到的第一个’(‘出栈但不输出;若为四则运算符,比较栈顶元素与当前元素的优先级:
如果 栈顶元素运算符优先级 >= 当前元素的优先级,出栈并顺序输出运算符直到 栈顶元素优先级 < 当前元素优先级,然后当前元素入栈;
如果 栈顶元素 < 当前元素,直接入栈。
5、重复第3点直到表达式扫描完毕。
6、顺序出栈并输出运算符直到栈顶元素为’\0’。
3. 程序实现
int Precedence(char sign)
{
switch(sign)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
case '%':
return 3;
case '(':
case'@':
default:
return 0;
}
}
/****************中缀表达式转换成后缀表达式********************/
void Change(char* s1,char* s2)
{
std::stack<char> T;//seqstack
int i=0,j=0;
char ch;
// SetNull(&T);
T.push('@');
ch=s1[i];
while(ch!='\0')
{
if(ch==' ')
ch=s1[++i];
else if(ch=='(')
{
T.push(ch);
//Push(&T,ch);
ch=s1[++i];
}
else if(ch==')')
{
while(T.top()!='(')
//while(GetTop(&T)!='(')
//s2[j++]=T.pop();
{ s2[j++] = T.top();
T.pop();
}
T.pop();
ch=s1[++i];
}
else if(ch=='+' || ch=='-' ||ch=='*' ||ch=='/' ||ch=='^' ||ch=='%')
{
char w=T.top();
while(Precedence(w)>=Precedence(ch))
{
s2[j++]=w;
T.pop();
w=T.top();
}
T.push(ch);
ch=s1[++i];
}
else
{
while((ch>='0' && ch<='9')||ch=='.'||(ch>='a' && ch<='b'))
{
s2[j++]=ch;
ch=s1[++i];
}
s2[j++]=' ';
}
}
ch=T.top();
while(ch!='@')
{
s2[j++]=ch;
T.pop();
ch=T.top();
}
s2[j++]='\0';
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout<<"please put in 中缀表达式"<<std::endl;
char s1[100] = {'\0'};
char s2[100] = {'\0'};
std::cin>>s1;
Change(s1,s2);
for(int i=0;i<strlen(s2);i++)
std::cout<<s2[i];
return 0;
}
程序改编自 逆波兰表达式-百度百科
4. STL–stack
stack 模板类的定义在头文件中。
_STD_BEGIN
template<class _Ty,
class _Container = deque<_Ty> >
class stack
{
...
}
_STD_END
注: #define _STD_BEGIN namespace std {
#define _STD_END }
第一个template参数代表元素类型,带有默认值的第二个template参数用来定义stack内部存放元素所用的实际容器,缺省采用deque.之所以采用deque而非vector,是因为deque移除元素时会释放内存,并且不必在重新分配时复制全部元素。
定义stack 对象的示例代码如下:
stack s;
stack s;
stack 的基本操作有:
入栈,如例:s.push(x);
出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。
访问栈顶,如例:s.top(),返回栈顶元素,但不会移除。
判断栈空,如例:s.empty(),当栈空时,返回true。
访问栈中的元素个数,如例:s.size()。