算法的用途:

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