今天写了一个表达式求值的程序。基本功能为:输入一个表达式比如23*34-21+(56*(45-1)) 然后程序求出结果。而且按照四则运算的优先级,同时支持括号。下面是程序运行的画面:
程序的难点在于把一个字符串分解为操作数和操作符并能正确处理各个操作符的优先级,特别是有括号的情况。本程序主要采用了传统的方法创建了操作数栈和操作符栈。关于操作符优先级的处理采用了一个关联数组来处理。还有很多其他的细节都在代码中。废话少说下面是程序的源代码:
#include<iostream>
#include<string>
#include<stack>
#include<map>
using namespace std;
class caculation
{
private:
string expression;//存储表达式
stack<int> num;//操作数栈
stack<char> operation;//操作符栈
map<char,int> oper_prio;//各个操作符的优先级
void set_priority();
public:
string inline &get_expression()
{
return expression;
}
void inline print_result()
{
cout<< "result:"<<num.top()<<endl;
}
void print_ifo();
void caculate();
friend istream & operator >>(istream & in,caculation & ca)
{
getline(in,ca.expression);
ca.expression +="#";//为了方便处理。
return in;
}
};
#include"caculate.h"
#include<cctype>
void caculation::print_ifo()
{
cout<<"请输入您要求的表达式,结束按q健。"<<endl;
cout<<"例如 23+12*4"<<endl;
}
void caculation::set_priority()
{
oper_prio['#']=1;
oper_prio[')']=2;
oper_prio['(']=2;
oper_prio['+']=3;
oper_prio['-']=3;
oper_prio['*']=4;
oper_prio['/']=4;
}//设置各个操作符的优先级。
void caculation::caculate()
{
int left,right,result;
string temp;
set_priority();
operation.push('#');
for(int i=0;i<expression.size();i++)
{
if(isdigit(expression[i]))
{
temp+=expression[i];
if(!isdigit(expression[i+1]))//如果下一位不是数字操作数结束。
{
num.push(atoi(temp.c_str()));
temp.clear();
}
}//提取出表达式中的操作数。
if(oper_prio[expression[i]])
{
while(true)
{
if(oper_prio[expression[i]]>oper_prio[operation.top()]||expression[i]=='(')//当操作符是“(”时直接入栈。
{
operation.push(expression[i]);
break;
}
else
{
if(operation.top()=='#')
break;
if(operation.top()=='(')//处理括号的情况,把括号出栈。
{
operation.pop();
break;
}
right=num.top();
num.pop();
left=num.top();
num.pop();
switch(operation.top())
{
case '+':
result=left+right;
break;
case'-':
result=left-right;
break;
case'*':
result=left*right;
break;
case'/':
if(right==0)
cout<<"表达式出现除零错误!";
result=left/right;
break;
}
num.push(result);
operation.pop();
}//end else
}//end while
}//end if
}//end for
}//end caculate
#include"caculate.h"
void main()
{
caculation ca;
ca.print_ifo();
while(ca.get_expression()!="q#")
{
cin>>ca;
ca.caculate();
ca.print_result();
cout<<"请输入下一个:"<<endl;
}
}
该程序还有很多问题比如:一、不能处理操作数为负数的情况。
二、计算完一个表达式之后没有对栈进行清理,导致随着运算的进行内存占用越来越多。