数据结构之栈与队列数学表达式的求值

数学表达式的计算

  
#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 直接出结果
}


代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值