算法的用途:

我的目的很简单,做一个24点牌的Flash小游戏,接受用户输入的表达式,然后计算结果。貌似在AS中没有可以直接计算字符串表达式的函数,所以只好自己写了。要计算这个表达式(带括号)首先得把括号去掉,括号真的是挺麻烦的一个东东,所以还得选后缀表达式-_-

算法基本思想:

使用三个数组,一个数组保存用户输入的表达式(中缀表达式),一个数组保存后缀表达式,一个数组作为运算符的栈。

从头到尾扫描中缀表达式,对不同类型的字符按不同情况处理;
1、如果是数字则直接放入后缀表达式数组;
2、如果是左括号则直接入栈;
3、如果是右括号,则把从栈顶直到对应左括号之间的运算符依次退栈,并清除对应的左括号;
4、对于运算符,如果该运算符的优先级大于栈顶优先级,则直接入栈,若该运算符的优先级小于等于栈顶优先级,则先把栈顶运算符出栈,写入后缀表达式数组,然后再入栈;
5、扫描完成后,取出栈中所有运算符,写入后缀表达式数组。

示例程序如下(面向过程的C(++)版,在VC6下编译通过):

引用内容:


/****************************/ 
  
 /*        www.afdream.com        */ 
  
 /*         Author:Fdream        */ 
  
 /*    引用此算法请保留此信息    */ 
  
 /****************************/ 
  

 #include<iostream.h> 
  

 const int MAX=40; 
  

 void main(void){ 
  
     char infix[MAX]={'#'}; 
  
     char oprator[MAX]={'@','#'}; 
  
     int opr=1; 
  
     char postfix[12]={'#'}; 
  
     int post=0; 
  
     int i,j,cnt=0,cntl; 
  
     char c; 
  

     //输入表达式,以等号结束 
  
     cin.get(c); 
  
     while(c!='='){ 
  
         infix[cnt]=c; 
  
         cnt++; 
  
         cin.get(c); 
  
     } 
  
     cntl=cnt; 
  

     for(i=0;i<cnt;i++){ 
  
         switch(infix[i]){ 
  
         //左括号就直接入栈 
  
         case '(': 
  
             cntl=cntl-2; 
  
             oprator[opr]=infix[i]; 
  
             opr++; 
  
             break; 
  
         //右括号则先退栈,直到遇见第一个左括号 
  
         case ')': 
  
             for(j=opr-1;j>0;j--){ 
  
                 if(oprator[j]!='('){ 
  
                     postfix[post]=oprator[j]; 
  
                     oprator[j]='#'; 
  
                     post++; 
  
                 } 
  
                 else{ 
  
                     oprator[j] = '#'; 
  
                     break; 
  
                 } 
  
             } 
  
             opr=j; 
  
             break; 
  
         case '*': 
  
         case '/': 
  
             //如果前一个运算符为*或/,则先退栈,再入栈,否则直接入栈 
  
             if (oprator[opr] == '*' || oprator[opr] == '/') { 
  
                 postfix[post] = oprator[opr]; 
  
                 oprator[opr]='#'; 
  
                 post++; 
  
             } 
  
             oprator[opr] = infix[i]; 
  
             opr++; 
  
             break; 
  
         case '+' : 
  
         case '-' : 
  
             //如果上一个运算符不是左括号也不是栈顶,则先退栈再入栈 
  
             if (oprator[opr-1] != '(' && oprator[opr-1] != '@') {             
  
                 postfix[post] = oprator[opr]; 
  
                 oprator[opr]='#'; 
  
             } 
  
             oprator[opr] = infix[i]; 
  
             opr++; 
  
             break; 
  
         default : 
  
             //如果是数字则直接进入后缀表达式数组 
  
             postfix[post] = infix[i]; 
  
             post++; 
  
             break; 
  
         } 
  
     } 
  

     //如果扫描完成,则退栈 
  
     for(j=opr-1;j>0;j--){ 
  
         if(oprator[j]!='@'){ 
  
             postfix[post]=oprator[j]; 
  
             oprator[j]='#'; 
  
         } 
  
         else 
  
             break; 
  
     } 
  

     //输出结果 
  
     for(i=0;i<cntl;i++) 
  
         cout << postfix[i]; 
  
     cout << endl; 
  
 }
/****************************/ 
  
 /*        www.afdream.com        */ 
  
 /*         Author:Fdream        */ 
  
 /*    引用此算法请保留此信息    */ 
  
 /****************************/ 
  

 #include<iostream.h> 
  

 const int MAX=40; 
  

 void main(void){ 
  
     char infix[MAX]={'#'}; 
  
     char oprator[MAX]={'@','#'}; 
  
     int opr=1; 
  
     char postfix[12]={'#'}; 
  
     int post=0; 
  
     int i,j,cnt=0,cntl; 
  
     char c; 
  

     //输入表达式,以等号结束 
  
     cin.get(c); 
  
     while(c!='='){ 
  
         infix[cnt]=c; 
  
         cnt++; 
  
         cin.get(c); 
  
     } 
  
     cntl=cnt; 
  

     for(i=0;i<cnt;i++){ 
  
         switch(infix[i]){ 
  
         //左括号就直接入栈 
  
         case '(': 
  
             cntl=cntl-2; 
  
             oprator[opr]=infix[i]; 
  
             opr++; 
  
             break; 
  
         //右括号则先退栈,直到遇见第一个左括号 
  
         case ')': 
  
             for(j=opr-1;j>0;j--){ 
  
                 if(oprator[j]!='('){ 
  
                     postfix[post]=oprator[j]; 
  
                     oprator[j]='#'; 
  
                     post++; 
  
                 } 
  
                 else{ 
  
                     oprator[j] = '#'; 
  
                     break; 
  
                 } 
  
             } 
  
             opr=j; 
  
             break; 
  
         case '*': 
  
         case '/': 
  
             //如果前一个运算符为*或/,则先退栈,再入栈,否则直接入栈 
  
             if (oprator[opr] == '*' || oprator[opr] == '/') { 
  
                 postfix[post] = oprator[opr]; 
  
                 oprator[opr]='#'; 
  
                 post++; 
  
             } 
  
             oprator[opr] = infix[i]; 
  
             opr++; 
  
             break; 
  
         case '+' : 
  
         case '-' : 
  
             //如果上一个运算符不是左括号也不是栈顶,则先退栈再入栈 
  
             if (oprator[opr-1] != '(' && oprator[opr-1] != '@') {             
  
                 postfix[post] = oprator[opr]; 
  
                 oprator[opr]='#'; 
  
             } 
  
             oprator[opr] = infix[i]; 
  
             opr++; 
  
             break; 
  
         default : 
  
             //如果是数字则直接进入后缀表达式数组 
  
             postfix[post] = infix[i]; 
  
             post++; 
  
             break; 
  
         } 
  
     } 
  

     //如果扫描完成,则退栈 
  
     for(j=opr-1;j>0;j--){ 
  
         if(oprator[j]!='@'){ 
  
             postfix[post]=oprator[j]; 
  
             oprator[j]='#'; 
  
         } 
  
         else 
  
             break; 
  
     } 
  

     //输出结果 
  
     for(i=0;i<cntl;i++) 
  
         cout << postfix[i]; 
  
     cout << endl; 
  
 }


 



 



============



要先设置一个运算符的栈st,从左只有扫描中缀表达式
1、如果遇到数字,直接放到后缀表达式尾;
2、如果遇到遇到运算符
   a:若此时站空,则直接入栈;
   b:循环:若栈st不空且栈顶运算符的优先级大于等于当前的运算符,则栈顶运算符出栈,置于后缀表达式尾;
   c:若栈st不空且栈顶运算符的优先级小于当前的运算符,则将此运算符直接入栈;
反复执行1,2,知道整个中缀表达式扫描完毕,若此时栈st不空,则将栈顶的运算符依次出栈,依次置于后缀表达式尾。