四则混合运算C++代码(中缀表达式)

 在复习算法的时候,栈的应用举例中有一项就是计算中缀表达式的四则混合运算。根据算法自己写了一下程序。

1、程序分为两块,一部分中缀转成后缀,一部分计算后缀。其中使用到了堆栈,我自己做了一个简单地模板栈。

2、中缀转后缀的程序,接受一个内涵中缀表达式的string,输出的是一个后缀表达式的string。中缀表达式的字符串校验自行解决,程序不负责。因为数字都是以字符的形式存在,因此一个完整的数字后面用一个“;”作为标识,以便计算式可以完整识别一个数字。

  例如:输入"90+(3-1)*3+10/2 ”输出即为“90;3;1;- 3;*+10;2;/+”

3、计算后缀表达式的结果程序,接受一个后缀表达式的string,循环读取其中每一个字符,如果是数字即放到字符串strNum之中,直到遇到“;”即将strNum中记录的完整数字的字符串转换成浮点类型,使用std::atof()函数,然后入栈。遇到符号即取出栈顶两个元素计算,结果入栈。最后栈里的唯一数字即结果,return。

 

首先中缀表达式转换成后缀表达式:

///2月28日中缀表达式转换成后缀表达式
//输入中缀表达式字符串infix,转化后返回后缀表达式字符串postfix
//输出串中,每一个数字后面放置一个;作为标识。因为数字使用char表达,234即三个char,“;”标识数字结束。做好数字完结标识后,即写入输出字符串中。
//遇到符号,左括号直接入栈;右括号时,将栈顶符号逐个取出写入输出字符串中,直到遇见左括号;
//运算符需循环与栈顶符号优先级进行比较:如果小于或者等于,取出栈顶符号写入输出字符串中,如果是左括号,直接入栈,如果优先级高于栈顶符号,入栈。
std::string InfixToPostfix(std::string infix)
{
	char current = 0;//读入的字符
	std::string postfix;//写入后缀表达式的字符串

	SqStack<char> mark;//符号入栈
	InitStack(&mark);

	std::map<char,int> priority;//运算符号优先级表
	priority['+'] = 0;
	priority['-'] = 0;
	priority['*'] = 1;
	priority['/'] = 1;
	
	for(int i = 0;i<infix.length();++i)//逐个读取中缀表达式字符串中的字符
	{
		current =infix[i];
		switch(current)
		{
		     case '0':case '1':case '2':case '3':case '4':case '5':
		     case '6':case '7':case '8':case '9':case '.':
			postfix.push_back(current);//如果是数字的话直接写入输出字符串。
		           break;
		     case '+':case '-':case '*':case '/':
			if(infix[i-1] != ')') postfix.push_back(';');//如果运算符的前一项不是右括号即说明前一个数字输入完毕,用;标识前面几个字符组成一个数字。
				if(!IsEmpty(mark))//如果符号栈非空,即比较目前符号与栈顶符号优先级,低于等于出栈,并写入输出字符串。
				{
					char tempTop;
					GetTop(mark,tempTop);
					while(tempTop != '(' && priority[current]<=priority[tempTop])
					{
						char tempOut;
						Pop(&mark,&tempOut);
						postfix.push_back(tempOut);
						if(IsEmpty(mark))//如果栈为空,跳出while循环
							break;
						GetTop(mark,tempTop);
					}
				}
				Push(&mark,current);//符号全部出栈或者遇到了'('或者大于栈顶符号的优先级,将新符号压入栈中。
				break;
			case '(':
				Push(&mark,current);//左括号直接入栈
				break;
			case ')':
				postfix.push_back(';');//右括号说明前方数字输入完成,标识一下。
				char tempTop;
				GetTop(mark,tempTop);
				while(tempTop !='(')//直到栈顶元素是左括号才停止循环
				{
					char tempOut;
					Pop(&mark,&tempOut);
					postfix.push_back(tempOut);//出栈并写入输出字符串中。
					GetTop(mark,tempTop);
				}
				char tempOut;
				Pop(&mark,&tempOut);//直接将左括号出栈。
				break;
			default:
				break;//忽略其他字符。
		}
	}
if(infix[infix.size()-1] != ')') postfix.push_back(';');//中缀表达式最后一个是数字需要加上;标识其是一个数字的结束,便于计算时统一识别数字结束。
	while(!IsEmpty(mark))//如果栈非空,全部出栈并写入输出字符串。
	{
		char tempOut;
		Pop(&mark,&tempOut);
		postfix.push_back(tempOut);
	}
	return postfix;//返回后缀表达式。
}

然后计算后缀表达式:

///计算后缀表达式结果
//输入为后缀表达式s,逐个读取字符,如果是数字即放入存放当前数字的字符串中,遇到“;”即将此字符串转换为float,
//使用std::atof(),参数接受const char*类型,字符串需使用.c_str()转化。
//完成数字识别转化后入栈,遇到符号即取出栈顶的两个数字计算,结果入栈。
//栈中最后的元素即为结果。
float Compute(std::string s)
{
	SqStack<float> waitForCompute;
	SqStack<float>* ptWait = &waitForCompute;
	InitStack<float>(ptWait);         //使用栈记录等待计算的数

	std::string strNum;
	float currNum = 0;

	float temNum1 = 0;
	float temNum2 = 0;
	for(std::string::const_iterator i = s.begin();i<s.end();++i)
	{
		switch(*i)
		{
		case '0':case '1':case '2':case '3':case '4':case '5':
		case '6':case '7':case '8':case '9':case '.':
			strNum.push_back(*i);
			break;
		case '+':
		    Pop(ptWait,&temNum1);
			Pop(ptWait,&temNum2);
			Push(ptWait, temNum2 + temNum1);
			break;
		case '-':
			Pop(ptWait,&temNum1);
			Pop(ptWait,&temNum2);
			Push(ptWait, temNum2 - temNum1);
			break;
		case '*':
			Pop(ptWait,&temNum1);
			Pop(ptWait,&temNum2);
			Push(ptWait, temNum2 * temNum1);
			break;
		case '/':
			Pop(ptWait,&temNum1);
			Pop(ptWait,&temNum2);
			Push(ptWait, temNum2 / temNum1);
			break;
		case ';':
			currNum = std::atof(strNum.c_str());//字符串转换为浮点型。
			strNum.clear();
			Push(ptWait,currNum);
			break;
		}
	}
    Pop(ptWait,&currNum);
	return currNum;

}


其中使用到了自定义的一个顺序栈:

const int MAXSIZE = 50;

template<class T> struct SqStack
{
	T data[MAXSIZE];
	int top;
};



template<class T> void InitStack(SqStack<T>* s);

template<class T>  void DestroyStack(SqStack<T>* s);

template<class T>  void ClearStack(SqStack<T>* s);

template<class T>  bool IsEmpty(SqStack<T> s);

template<class T>  void GetTop(SqStack<T> s,T& e);

template<class T>  void Push(SqStack<T>* s,T e);

template<class T>  void Pop(SqStack<T>* s, T* e);

template<class T>  int StackLength(SqStack<T> s);


 


 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值