算法的用途:

我的目的很简单,做一个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不空,则将栈顶的运算符依次出栈,依次置于后缀表达式尾。