/* 将中缀表达式(a+b)转换为后缀表达式(ab+)的算法思想:   
   ·当读到数字直接送至输出队列中   
   ·当读到运算符t时,   
      a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;     
      b.t进栈   
   ·读到左括号时总是将它压入栈中   
   ·读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号。   
   
      运用后缀表达式进行计算的具体做法:   
   ·建立一个栈S   
   ·从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,读到运算符则从栈中依次弹出两个数分别到Y和X,然后以“X   运算符   Y”的形式计算机出结果,再压加栈S中   
   ·如果后缀表达式未读完,就重复上面过程,最后输出栈顶的数值则为结束 */
 #include <iostream>
#include <string>
using namespace std;
 char ex[100];//存储后缀表达式
char str[100];//存储算术表达式
char stack[100];//作为栈使用
char ch;//当前判断的字符
int i=0;//i为算术表达式str的下标
int t;//t为后缀式ex的下标
int top=0;//top为栈顶
void trans();//转换函数
void compute();//计算后缀式的值
 void trans()//将中缀式转换为后缀式
{
cout<<"输入一个算术表达式,以#号结束:"<<endl;
while(str[i]!='#')//中缀式以#号结束
{
   i++;//因为i的初值设为0
   cin>>str[i];
}
//开始扫描
t=1;
i=1;
ch=str[i];
i++;//i指向当前扫描字符的下一位
while(ch!='#')//逐个扫描,直至遇到#号结束
{
   switch(ch)
   { 
   case'('://遇到(,进栈
    top++;
    stack[top]=ch;
    break; 
   case')'://遇到),将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至后缀式队列后,再丢弃左括号。
    while(stack[top]!='(')
    {
     ex[t]=stack[top];
     top--;
     t++;
    }
    top--;//丢弃(
    break;
   case'+':
   case'-':
    while(top!=0 && stack[top]!='(')
    {
     ex[t]=stack[top];
     top--;
     t++;
    }
    top++;//因为top的初值为0
    stack[top]=ch;
    break;
   case'*':
   case'/':
    while(stack[top]=='*'|| stack[top]=='/')
   {
    ex[t]=stack[top];
    top--;
    t++;
   }
   top++;
   stack[top]=ch;
   break;
  
   /*注意!除操作数外,其它符号都要用到栈*/
   default:while(ch>='0' && ch<='9')//遇到操作数直接送至后缀式队列
     {
      ex[t]=ch;
      t++;
      ch=str[i];
      i++;//此时i指向操作数之后的运算符的后一位!!
     }
    i--;//要在操作数之后,运算符之前添加空格符
    ex[t]=' ';//用空格符隔开
    t++;
    }//switch结束
    ch=str[i];//仿照default中的,返回添加空格符之前的操作
   i++;
}//结束while
 
while(top!=0)//仍有运算符在栈中
{
   ex[t]=stack[top];
   t++;
   top--;
}
ex[t]=' ';//不能省,若省掉则无法进入compute函数??
for(int j=1;j<i-1;j++)
   cout<<str[j];
cout<<"的后缀式为:";
for(j=1;j<t;j++)
cout<<ex[j];
 }
 void compute()
{
float stack[100];//作为栈使用
int d;//用于存放当前的计算结果
char ch;
int t=1;
int top =0;
ch=ex[t];
t++;
 while(ch!=' ')//此空格符为后缀式中的最后一个字符,与上文中的" ex[t]=' '; "相对应
{
   switch(ch)
   {
   case'+':
    stack[top-1]=stack[top-1]+stack[top];
    top--;
    break;
   case'-':
    stack[top-1]=stack[top-1]-stack[top];
    top--;
    break;
   case'*':
    stack[top-1]=stack[top-1]*stack[top];
    top--;
    break;
   case'/':
    if(stack[top]!=0)
     stack[top-1]=stack[top-1]/stack[top];
    else
    {
     cout<<"\n除零错误!"<<endl;
     exit(0);//异常退出
    }
    top--;//两个操作数算出一个结果存放到栈顶,那两操作数便可丢弃,故top-1
    break;
   default:
    d=0;
    while(ch>='0' && ch<='9')
    {
     d=10*d+ch-'0';//将数字字符转化为对应的数值,*10是与大于10的数值时要进位
     ch=ex[t];
     t++;
    }
    top++;
    stack[top]=d;//栈顶存放当前计算结果
  
   }//switch结束
   ch=ex[t];//跳过空格符,扫描下一个运算符或操作数
   t++;
}
cout<<"\n计算结果为:"<<stack[top]<<endl;
}
 void main()
{
trans();
compute();
}
 结果如图所示:
 