刚学C++,一个表达式求值的问题,困扰我好久,昨天终于搞掂了,发上来给在家分享下哈哈!
#include "stdafx.h"
#include "Constant.h"
#include<iostream>
#include"MathCalc.h"
#include<string.h>
#include<ctype.h>
#include<math.h>
#include <stdlib.h>
using namespace std;
int MathCalc::aiPriority[9][9]={
{ 1, 1, -1, -1, -1, -1, 1, 1, -1},
{ 1, 1, -1, -1, -1, -1, 1, 1, -1},
{ 1, 1, 1, 1, -1, -1, 1, 1, -1},
{ 1, 1, 1, 1, -1, -1, 1, 1, -1},
{ 1, 1, 1, 1, -1, -1, 1, 1, -1},
{ -1, -1, -1, -1, -1, -1, 0,255, -1},
{ 1, 1, 1, 1, 1,255, 1, 1, 1},
{ -1, -1, -1, -1, -1, -1, -1, 0, -1},
{ 1, 1, 1, 1, 1, -1, 1, 1, -1}
};
/*运算符优先级表
=========================================
* + - * / ^ ( ) # @
* + > > < < < < > > <
* - > > < < < < > > <
* * > > > > < < > > <
* / > > > > < < > > <
* ^ > > > > < < > > <
* ( < < < < < < = <
* ) > > > > > > > >
* # < < < < < < < = <
@ > > > > > < > > <
*
*=========================================
*/
char * MathCalc::ErrMsg[5] = {
"None Error.",
"There is not expression for calculating.",
"Invalid usage of operator.",
"Lack operator for calculating.",
"Lack argument for calculating."
};
MathCalc::MathCalc(){
m_StackOptr = new Stack();
m_StackOpnd = new Stack();
}
MathCalc::~MathCalc(){
delete m_strExpression;
delete m_StackOptr;
delete m_StackOpnd;
}
char * MathCalc::getCalc(){
return m_strExpression;
}
int MathCalc::GetErrCode(){
return m_ErrCode;
}
char * MathCalc::GetErrMsg(){
return MathCalc::ErrMsg[-m_ErrCode];
}
void MathCalc::setStackOptr(Stack * a_StackOptr){
m_StackOptr = a_StackOptr;
}
Stack * MathCalc::getStackOptr(){
return m_StackOptr;
}
void MathCalc::setStackOpnd(Stack * a_StackOpnd){
m_StackOpnd = a_StackOpnd;
}
Stack * MathCalc::getStackOpnd(){
return m_StackOpnd;
}
double MathCalc::Calc(){
Token token;
int lastTokenType = Constant::BEGIN;
if(m_strExpression[0] == 0){
m_ErrCode = Constant::ERR_NO_EXPRESSION;
return m_ErrCode;
}
m_StackOptr->InitStack();
m_StackOpnd->InitStack();
token.setType(Constant::BEGIN);
m_StackOptr->Push(&token);
strcat(m_strExpression, "#");
m_strExpression = GetToken(&token);
while(Constant::EMPTY!=token.getType()){
if(Constant::ERROR == token.getType()){
m_ErrCode = Constant::ERR_INVALID_CHAR;
return m_ErrCode;
}
switch(token.getType()){
case Constant::NUMBER:
m_StackOpnd->Push(&token);
lastTokenType=token.getType();
break;
case Constant::PLUS:
case Constant::MINUS:
if(lastTokenType!=Constant::NUMBER&&lastTokenType!=Constant::RPAREN){
//判断如果结尾不是一个操作数或者不是一个右括号
token.setType(Constant::SPECIAL);
//将操作符的类型设置为SPECIAL(负号)
lastTokenType=token.getType();
//将操作符的类型置赋给lastTokenType;
ProcessOpt(&token);
//将Token的引用作为参数ProcessOpt;
break;
}
case Constant::TIMERS:
case Constant::DIVIDE:
case Constant::POWER:
if(lastTokenType!=Constant::NUMBER && lastTokenType!=Constant::RPAREN)
{
m_ErrCode=Constant::ERR_INVALID_OPT;
return m_ErrCode;
}
lastTokenType=token.getType();
ProcessOpt(& token);
break;
case Constant::LPAREN:
if(lastTokenType==Constant::NUMBER)
{
m_ErrCode=Constant::ERR_LACK_OPT;
return m_ErrCode;
}
lastTokenType=token.getType();
ProcessOpt(& token);
break;
case Constant::RPAREN:
if(lastTokenType!=Constant::NUMBER)
{
m_ErrCode=Constant::ERR_LACK_ARGUMENT;
return m_ErrCode;
}
lastTokenType=token.getType();
ProcessOpt(&token);
break;
case Constant::END:
if(lastTokenType!=Constant::NUMBER && lastTokenType!=Constant::RPAREN)
{
m_ErrCode=Constant::ERR_LACK_ARGUMENT;
return m_ErrCode;
}
lastTokenType = token.getType();
ProcessOpt(&token);
break;
}
m_strExpression = GetToken(&token);
}
if(!m_StackOptr->IsEmpty()){
m_StackOptr->Pop(& token);
m_ErrCode = Constant::ERR_LACK_ARGUMENT;
return m_ErrCode;
}
if(m_StackOpnd->GetSize() > 1){
m_ErrCode = Constant::ERR_LACK_OPT;
return m_ErrCode;
}
m_ErrCode = Constant::ERR_NONE;
m_StackOpnd->Pop(& token);
return token.getOptrValue();
}
/*
*处理表达式元素压栈
*
*/
char * MathCalc::GetToken(Token * a_pToken){
char * pchNextChar = NULL;
int iLen = 0;
if(NULL == m_strExpression || NULL == a_pToken){
a_pToken->setType(Constant::EMPTY);
return NULL;
}
pchNextChar = m_strExpression;
while(' ' == * pchNextChar || '/t' == * pchNextChar){
pchNextChar++;
}
if('/0' == * pchNextChar){
a_pToken->setType(Constant::EMPTY);
return pchNextChar;
}
switch(* pchNextChar){
case '+':
a_pToken->setType(Constant::PLUS);
pchNextChar++;
return pchNextChar;
case '-':
a_pToken->setType(Constant::MINUS);
pchNextChar++;
return pchNextChar;
case '*':
a_pToken->setType(Constant::TIMERS);
pchNextChar++;
return pchNextChar;
case '/':
a_pToken->setType(Constant::DIVIDE);
pchNextChar++;
return pchNextChar;
case '^':
a_pToken->setType(Constant::POWER);
pchNextChar++;
return pchNextChar;
case '(':
a_pToken->setType(Constant::LPAREN);
pchNextChar++;
return pchNextChar;
case ')':
a_pToken->setType(Constant::RPAREN);
pchNextChar++;
return pchNextChar;
case '#':
a_pToken->setType(Constant::END);
return NULL;
default:
break;
}
if(isdigit(*pchNextChar)){
iLen = 0;
a_pToken->setType(Constant::NUMBER);
while(isdigit(*pchNextChar)){
a_pToken->setOpndID(*pchNextChar ,iLen);
pchNextChar++;
iLen++;
}
if('.' == * pchNextChar){
a_pToken->setOpndID(* pchNextChar , iLen);
pchNextChar++;
iLen++;
if(isdigit(*pchNextChar)){
while(isdigit(* pchNextChar)){
a_pToken->setOpndID(*pchNextChar , iLen);
pchNextChar++;
iLen++;
}
}
else{
a_pToken->setOpndID('/0' , iLen);
a_pToken->setType(Constant::ERROR);
return pchNextChar;
}
}
a_pToken->setOpndID('/0' , iLen);
a_pToken->setOptrValue(atof(a_pToken->getOpndID()));
return pchNextChar;
}
a_pToken->setType(Constant::ERROR);
a_pToken->setOpndID(* pchNextChar , 0);
a_pToken->setOpndID('/0' , 1);
return pchNextChar;
}
/*
*根据运算符优先级进行运算。
*/
int MathCalc::ProcessOpt(Token * a_pToken){
Token topToken;
char bFinished = 0;
if(m_StackOptr->IsEmpty()){
m_StackOptr->Push(a_pToken);
return Constant::ERR_NONE;
}
while(!bFinished && !m_StackOptr->IsEmpty()){
m_StackOptr->Top(&topToken);
switch(aiPriority[topToken.getType()][a_pToken->getType()]){
case 0:
m_StackOptr->Pop(&topToken);
a_pToken = NULL;
bFinished = 1;
break;
case 1:
DoCalc();
break;
case -1:
bFinished = 1;
break;
default:
m_ErrCode = Constant::ERR_INVALID_OPT;
return m_ErrCode;
}
}
if(a_pToken != NULL){
m_StackOptr->Push(a_pToken);
}
return Constant::ERR_NONE;
}
/*
*执行单目运算
*参数说明:无
*返回值:错误代码
*
*/
int MathCalc::DoCalc(){
/*
*opt 操作符
*lNumber 左操作数
*rNumber 右操作数
*增加对负号的处理
*/
Token opt , lNumber , rNumber;
m_StackOptr->Pop(& opt);
if(opt.getType()==Constant::SPECIAL){
//如果作操数的类型为特殊符号
m_StackOpnd->Pop(&lNumber);
//弹出操作数
lNumber.contrary();
//对其进行取反运算
m_StackOpnd->Push(&lNumber);
//将操作数压入堆栈
return Constant::ERR_NONE;
}
m_StackOpnd->Pop(& rNumber);
m_StackOpnd->Pop(& lNumber);
switch(opt.getType()){
case Constant::MINUS:
lNumber.setOptrValue(lNumber.getOptrValue()-rNumber.getOptrValue());
break;
case Constant::PLUS:
lNumber.setOptrValue(lNumber.getOptrValue()+rNumber.getOptrValue());
break;
case Constant::TIMERS:
lNumber.setOptrValue(lNumber.getOptrValue()*rNumber.getOptrValue());
break;
case Constant::DIVIDE:
lNumber.setOptrValue(lNumber.getOptrValue()/rNumber.getOptrValue());
break;
case Constant::POWER:
lNumber.setOptrValue(pow(lNumber.getOptrValue(),rNumber.getOptrValue()));
break;
default:
return Constant::ERR_INVALID_OPT;
}
m_StackOpnd->Push(&lNumber);
return Constant::ERR_NONE;
}
/*
*主方法
*/
void MathCalc::Main(){
char buffer[129];
do{
cout<<"input Expression:/n";
cin>>buffer;
if(buffer[0] != 0){
m_strExpression = buffer;
m_Result = Calc();
m_ErrCode = GetErrCode();
if(m_ErrCode == Constant::ERR_NONE){
cout<<"Expression Result:"<<m_Result<<endl;
}
else{
cout<<"Error:"<<GetErrMsg()<<endl;
}
}
}while(buffer[0] != 0);
}