|
后缀表达式求值及校验 下载源代码 摘要: 本程序是一个完整的后缀表达式计算,主要用栈的操作实现,本程序封装了CStack类实现栈的操作,本程序最大的特色在于运用动态监视表达式的算法对表达式进行数据校验,对一切合法的表达式进行计算,检验出所有任何非法表达式并提示。 关键字:后缀表达式,校验 题目:后缀表达式求值。 输入:2 3 * 1 - 算法分析: 后缀表达式相对于普通的表达式来说,起优点在于不需要括号。所以方便的计算机的处理,通常对于后缀表达式才用栈的数据结果来实现,从左往右扫描表达式,如果遇到的是数字,则把数字压入栈中;若遇到的是运算符号,则提取栈的的2个元素进行计算,讲计算结果压栈,若最后栈内只剩下一个数字,这就是后缀表达式的计算结果。在此基础上,考虑到对后缀表达式的校验,根据后缀表达式计算的特性,编写了一些函数,对后缀表达式进行校验,应该可以对任何错误的后缀表达式都能校验出来并提示出错,在程序中设置了一些状态,一旦出现了错误状态,立刻停止计算过程,立即报错。 总体设计:
类CStack的定义: class CStack类CStack的实现: CStack::CStack(){ for(int i=0;i<=50;i++)num[i]=0; sum=0; flag=1;//假设所有操作均合法 popcount=0; pushcount=0;} int CStack::getflag(){ return flag;}int CStack::getsum(){ return sum;}void CStack::setflag(int tempflag){flag=tempflag;}int CStack::getcount(){return (pushcount*2-popcount)/2;}void CStack::Pop(){if(sum>=1)//判断是否非法操作 {num[sum]=0;sum--;popcount++;}else{flag=0;}}void CStack::Push(int temp){sum++;num[sum]=temp;pushcount++;}int CStack::Top(){if(sum>=1)//判断是否非法操作 {return num[sum];}else{flag=0;}}
主程序,这里完成了计算,以及对表达式检验的全部过程: void CB05031126Dlg::OnCalculate() {// TODO: Add your control notification handler code hereUpdateData(TRUE);m_expression.TrimLeft();m_expression.TrimRight();m_expression=trimblank(m_expression);CStack s;int i=0;int j,k;int ntemp;//临时操作数int ntemp1;//临时操作数int ntemp2;//临时操作数int result;//运算结果//int opNum=getop(m_expression);if(check(m_expression)==1)//检验非法字符{while((i<m_expression.GetLength())&&(s.getflag()!=0)){if((m_expression[i]==''+'')||(m_expression[i]==''-'')||(m_expression[i]==''*'')||(m_expression[i]==''/'')){if(m_expression[i]==''+'')//完成加法运算{ntemp1=s.Top();s.Pop();ntemp2=s.Top();s.Pop();ntemp=ntemp1+ntemp2;s.Push(ntemp);}if(m_expression[i]==''-'')//完成减法运算{ntemp1=s.Top();s.Pop();ntemp2=s.Top();s.Pop();ntemp=ntemp2-ntemp1;s.Push(ntemp);}if(m_expression[i]==''*'')//完成乘法运算{ntemp1=s.Top();s.Pop();ntemp2=s.Top();s.Pop();ntemp=ntemp1*ntemp2;s.Push(ntemp);}if(m_expression[i]==''/'')//完成除法运算{ntemp1=s.Top();s.Pop();ntemp2=s.Top();s.Pop();if(ntemp1!=0){ntemp=ntemp2/ntemp1;s.Push(ntemp);}else{s.setflag(0);}}k=k+2;}else{ntemp=m_expression[i]-48;k=i+1;while((k<m_expression.GetLength())&&(m_expression[k]!='' '')&&(m_expression[k]!=''+'')&&(m_expression[k]!=''-'')&&(m_expression[k]!=''*'')&&(m_expression[k]!=''/'')){k++;}for(j=i+1;j<k;j++)//讲表达式中的数字字符转换为整型ntemp=ntemp*10+(m_expression[j]-''0'');s.Push(ntemp);}i=k+1;}if((s.getflag()!=0)&&(s.getcount()-getop(m_expression)==1)&&(s.getsum()==1)){result=s.Top();m_result.Format("%d",result);UpdateData(FALSE);}else{MessageBox("表达式错误!请重新输入!");}}else{MessageBox("表达式错误!请重新输入!");}}
附言:
本程序为南京邮电大学软件工程专业程序设计实验,我在做的时候附加实现了对表达式的校验,理论上应该可以检测出任何错误的表达式。 |