数学表达式的计算
#pragma once
#include <stack>
#include <deque>
using namespace std;
typedef struct {
double opnd; //操作数
char optr; //运算符
}Item;
const int COUNTS =6 ; //“+-*/()”一共六个运算符,照抄书上的优先级表格(没有用到'#')
const char PRECEDE[COUNTS][COUNTS] = {
{ '>', '>' ,'<' ,'<' ,'<','>'},
{ '>','>','<','<','<' ,'>',},
{ '>','>','>', '>', '<', '>' },
{ '>','>','>','>', '<','>'},
{ '<', '<', '<', '<', '<', '='},
{ '>', '>', '>', '>', '!', '>'},
};
double Value(double a, char optr, double b);
char Precede(char optr1, char optr2);
double EvaluateExpression(stack<Item> & stackExpression, deque<Item> dequeExpression, const char * ptrExpression);
实现接口
#include <regex>
#include <string>
#include <stack>
#include <deque>
#include"regular expression.h"
using namespace std;
double EvaluateExpression(stack<Item> & stackExpression, deque<Item> dequeExpression, const char * ptrExpression)
{
int nLength; //表达式长度
double opnd1, opnd2; //两个double类型的数
Item item; //Item类型对象
const char * ptrAnalyze;
string strToptr;
regex rx("\\d+\\.?\\d*"); //正则表达式
cmatch mr; //match_result<const char*>对象
nLength = strlen(ptrExpression);
for (ptrAnalyze = ptrExpression; ptrAnalyze < ptrExpression + nLength; )
{
if (strchr("+-*/()", *ptrAnalyze) == nullptr) //不是运算
{
regex_search(ptrAnalyze, mr, rx); //使用正则表达式找出第一个数字
ptrAnalyze += mr.length(); //ptrAnalyze越过这个数字
strToptr = mr.str();
dequeExpression.push_back({ atof(strToptr.c_str()),'\0' });//atof()将字符串转化为浮点数,将数字放入队列最后
}
else //是运算符
{
if (stackExpression.empty()) //栈为空,直接把运算符放入栈
{
stackExpression.push({ 0.0,*ptrAnalyze });
ptrAnalyze++; //越过这个运算符
}
else
{
item = stackExpression.top(); //提取栈顶的运算符
switch (Precede(item.optr, *ptrAnalyze)) //和栈顶运算符比较优先级
{
case '<':
stackExpression.push({ 0.0,*ptrAnalyze }); //优先级小就入栈
ptrAnalyze++; //越过这个运算符
break;
case '=':
stackExpression.pop(); //相等就使栈顶元素退栈( 其实就是当 '(' 和 ')' 相遇的时候,将一对括号都抛弃)
ptrAnalyze++;
break;
case '>':
item = stackExpression.top(); //优先级比栈顶的运算符高,就使栈顶运算符退栈并放入队列最后
dequeExpression.push_back(item);
stackExpression.pop();
break; //注意ptrAnalyze没有自增,依然指向此运算符,直到比较结果为'<'或'='此运算符才被处理
default:
break;
}
}
}
}
while (!stackExpression.empty()) //将栈中剩余的运算符依次取出放入队列最后
{
item = stackExpression.top();
dequeExpression.push_back(item);
stackExpression.pop();
}
while (!dequeExpression.empty()) //将队列中的元素从头部依次放入栈中
{
item = dequeExpression.front();
if (item.optr) //如果是运算符,判断是几元运算符,取栈顶元素进行计算,结果放入栈顶
{
opnd2 = stackExpression.top().opnd;
stackExpression.pop();
opnd1 = stackExpression.top().opnd;
stackExpression.pop();
stackExpression.push({ Value(opnd1,item.optr,opnd2),'\0' });
dequeExpression.pop_front();
continue;
}
stackExpression.push(item); //如果不是运算符,就将操作数放入栈顶
dequeExpression.pop_front();
}
return stackExpression.top().opnd;
}
char Precede(char optr1, char optr2) //判断运算符优先级
{
int i, n;
switch (optr1)
{
case '+':i = 0;break;
case '-':i = 1;break;
case '*':i = 2;break;
case '/':i = 3;break;
case '(':i = 4;break;
case ')':i = 5;break;
default:
break;
}
switch (optr2)
{
case '+':n = 0;break;
case '-':n = 1;break;
case '*':n = 2;break;
case '/':n = 3;break;
case '(':n = 4;break;
case ')':n = 5;break;
default:
break;
}
return PRECEDE[i][n]; //头文件二维char数组
}
double Value(double a, char optr, double b) //二元操作符的运算
{
switch (optr)
{
case '+':return a + b;
case '-':return a - b;
case '*':return a*b;
case '/':return a / b;
default:
return 0.0;
break;
}
}
#include <iostream>
#include <regex>
#include <string>
#include <stack>
#include <deque>
#include "regular expression.h"
using namespace std;
int main()
{
string strCin; //表达式字符串
stack<Item> stackExpression; //一个堆
deque<Item> dequeExpression; //一个队列
const char * ptrExrpression;
cin >> strCin; //输入表达式
ptrExrpression = strCin.c_str(); //string对象返回一个const char *
cout << EvaluateExpression(stackExpression, dequeExpression, ptrExrpression) << endl; //调用EvaluateExpression 直接出结果
}
代码下载