C++ Primer 练习 9.52 题

初来咋到 请多多关照哈

C++primer 9.52的练习,之前因为自己学识不够,在看看题目:

练习 9.52:

           使用stack处理括号化的表达式。当你看到一个左括号,将其记录下来。当你在一个左括号之后看到一个右括号,从stack中pop对象,直至遇到左括号,将左括号也一起弹出栈。然后将一个值(括号内的运算结果)push到栈中,表示一个括号化的(子)表达式已经处理完毕,被其运算结果所替代。


  这样的题目。。。额 ,当时有点蒙蔽,什么跟什么,因为完全没接触过(所以。逃

  不要嫌弃哈,因为我是新手哈,还在学,数据结构把还是

  然后老老实实地查了题目  之后知道是所谓的中缀表达式、后缀表达式、前缀表达式。(额 我还是太弱了

  之后借鉴 另一个博主地文章,看了大概地代码自己写了一个,欸,怎么说呢,也是跟那个博主一个,依葫芦画瓢把,依自己地逻辑写出来 挺好地。

  下面是链接:  键客小E   (这样应该不算转载把) 

  思路都是差不多的! 下面放我的代码 (

  代码质量不是很好,可以的话,大家做下参考把。有什么不足的地方麻烦请指教一下 谢谢 ,也可以看上面的前辈写的 这里应该不能@把 哦算了

  

#include <iostream>
#include <string>
#include <stack>
#include <vector>
using namespace std;

void calculate(stack<int>  &operd, string oper)
{
	if (oper == "-")
	{
		int  val2 = operd.top();
		operd.pop();
		int val1 = operd.top();
		operd.pop();
		int result = val1 - val2;
		operd.push(result);
	}
	else if (oper == "+")
	{
		int  val1 = operd.top();
		operd.pop();
		int val2 = operd.top();
		operd.pop();
		int result = val1 + val2;
		operd.push(result);
	}
	else if (oper == "*")
	{
		int  val1 = operd.top();
		operd.pop();
		int val2 = operd.top();
		operd.pop();
		int result = val1 * val2;
		operd.push(result);
	}
	else if (oper == "/")
	{
		int  val2 = operd.top();
		operd.pop();
		int val1 = operd.top();
		operd.pop();
		int result = val2 ? (val1 / val2) : val2; //这里除法要特别计算 除数不能为0
		operd.push(result);
	}
}

int priority(string op)
{
	int pri;
	if (op == "(") //( 都小于其他 
		pri = 0;
	else if (op == "+" || op == "-")
		pri = 1;
	else if (op == "*" || op == "/")
		pri = 2;
	return pri;
}

vector<string> Amend(string s)
{
	size_t len = s.size();
	vector<string> exp;
	size_t pos = 0;
	while ((pos = s.find_first_of(" ()/*-+0123456789", pos)) != string::npos)
	{
		if (s[pos] == '(' || s[pos] == ')' || s[pos] == '+' || s[pos] == '-' || s[pos] == '/' || s[pos] == '*')
		{
			exp.push_back(s.substr(pos, 1));//返回字符串
			pos++;//加1继续找
		}
		else if (s[pos] == ' ')
		{
			pos++;
			continue;
		}
		else
		{
			size_t p;
			exp.push_back (to_string(stoi(s.substr(pos),&p)));
			pos = p + pos;
		}
	}

	return exp;
}

int expression(string str)
{
	stack<int> oand; //这个压入操作数 栈
	stack<string> otor; //这个是压入操作符 栈

	vector<string> exp = Amend(str);//修正
	size_t len = exp.size(); //修正之后的表达式大小

	for (size_t ix = 0; ix != len; ++ix)
	{
		string token = exp[ix]; //循环逐步读取 每个 标记
		if (token == "+" || token == "/" || token == "-" || token == "*")
		{
			if (otor.size() == 0)
				otor.push(token);
			else //进到这肯定有操作符
			{
				int pri_token = priority(token);//现在的操作符的优先级
				string stoken = otor.top();
				int pri_stack = priority(stoken);//在栈的操作符的优先级

				if (pri_token > pri_stack)
					otor.push(token);
				else
				{
					while (pri_token <= pri_stack) //当前的操作符小于栈里的操作符
					{
						otor.pop();
						calculate(oand, stoken); 
						if (otor.size() > 0) //如果操作符栈里还有
						{
							stoken = otor.top(); //再次读取当前操作符栈里的操作符
							pri_stack = priority(stoken); //这里计算优先级
						}
						else
							break;
					}
					otor.push(token); //压入新的
				}
			}
		}
		else if (token == "(") //直接压入(
			otor.push(token);
		else if (token == ")") // 这里计算圆括号里的表达式
		{
			if (otor.top() == "(")
			{
				otor.pop();
				break;
			}
			else
			{
				while (otor.top() != "(")
				{
					string stor = otor.top();
					calculate(oand, stor);
					otor.pop();
				}
				otor.pop();  //弹出(
			}
		}
		else
			oand.push(stoi(token)); //stoi 直接 转换 字符串 
	}
	while (otor.size() != 0) //如果再之后的里面还剩余操作符和操作数
	{
		string stor = otor.top();
		calculate(oand, stor);
		otor.pop();
	}
	return oand.top(); //返回最终值
}

int main()
{
	string str("(12+12)*2/2-(1+1)*2");
	cout << expression(str) << endl;
	for (auto i : Amend(str))
		cout << i << ' ';
	cout << endl;
	
	return 0;
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雫和春的故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值