蓝桥算法训练 表达式计算

本文参考博客http://www.cnblogs.com/z-y-p/p/3676945.html

问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

思路:

      之前刷题注重速度,许多问题不是十分透彻就上传了,导致遗忘的很快。。。我在写这道题的时候花费了

不少脑筋,下面我来讲讲思路

做此题第一步:

           将中缀表达式转换成后缀表达式,这个不能熟练转换那么这道题就没法做,转换方法参考这里http://www.nowamagic.net/librarys/veda/detail/2307 网上有很多教程我就不重复了


会转成后缀表达式后我们再来,以表达式2*(3+5)为例,用图模拟代码运行过程

最开始将符号栈入一个“(”,防止栈空,会出错

蓝桥算法训练 表达式计算_第1张图片

2进入数值栈

蓝桥算法训练 表达式计算_第2张图片

*号进符号栈

蓝桥算法训练 表达式计算_第3张图片

 ( 进符号栈

蓝桥算法训练 表达式计算_第4张图片

3进数值栈

蓝桥算法训练 表达式计算_第5张图片

+ 进符号栈

蓝桥算法训练 表达式计算_第6张图片

5进数值栈

蓝桥算法训练 表达式计算_第7张图片

检测到"(" 不入栈, 而是将符号栈中的")" 之上的运算符提出来,供给栈顶次顶元素运算,并将栈顶和次顶两个元素删除得到的新的值存入数值栈,在将"("也删掉,得到如图

蓝桥算法训练 表达式计算_第8张图片

然后中缀表达式遍历结束了,但还有8和2没有通过*运算,这时候最开始通过strcat将“.”连接到中缀表达式后面

就起作用了,碰到“.”,就按碰到+-运算符的处理方案一样,运算后如图


蓝桥算法训练 表达式计算_第9张图片

最后在将数值栈栈顶取出打印就ok啦

代码

#include
#include
#include
#include
using namespace std;
stack stack_ch;//符号栈 
stack stack_num; //数值栈 
char str[1000]; //输入的中缀表达式 
char number[100]; //用来将字符串中的数字变成int型的数组 

void js1()//这个函数只接收+-号,+-号等级最低,运算符栈中除了括号外 都可以取出运算 
{
	int num1,num2;
	while (stack_ch.top()!='(')  //从运算符栈中取一个运算符 对数值栈顶和次顶元素进行运算 
	{
		num1=stack_num.top();//取出一个数
		stack_num.pop();//弹出这个数
		num2=stack_num.top();
		stack_num.pop();
		switch (stack_ch.top())
		{
			case '+':
				num2+=num1;
			    break;
			case '-':
				num2-=num1;
				break;
			case '*':
				num2*=num1;
				break;
			case '/':
				num2/=num1;
				break;
		 } 
		 stack_num.push(num2);//将计算结果入数值栈
		  stack_ch.pop();//删除已经用过的符号 
	}
}
void js2()//只接收*/运算符 
{
	int num1,num2;
	while (stack_ch.top()=='*' || stack_ch.top()=='/') //栈中只有*/优先级大于*/  
	{
		num1=stack_num.top();
		stack_num.pop();
		num2=stack_num.top();
		stack_num.pop();
		switch (stack_ch.top())
		{
			case '*':
			    num2*=num1;
				break;
			case '/':
			    num2/=num1;
				break; 
		}
		stack_ch.pop();
		stack_num.push(num2);
	}
}
int main()
{
	int i,k=0,s;
	char c[5]=".";
	stack_ch.push('(');
	gets(str);
	strcat(str,c);
	for (i=0;str[i];i++)
	{
		if (str[i]>='0'&&str[i]<='9')//为数字
		  {
		  	number[k++]=str[i];
		  	continue;
		  }
		  number[k]='\0'; //变成字符串\0结尾 
		  if (number[0]!='\0')
		  {
		  s=atoi(number);
		  number[0]='\0';
		  stack_num.push(s); //将字符串转换成整型,放入数值栈中 
	      }
		  k=0; 
	    	switch(str[i])//+-(这3个符号入js1函数,*/入js2函数 ,优先级不同要分开计算 
	    	{
	    		case '+':  
	    			js1();
	    			stack_ch.push('+');
	    			break;
	    		case '-':
	    			js1();
	    			stack_ch.push('-');
	    			break;
	    		case '*':
	    			js2();
	    			stack_ch.push('*');
	    			break;
	    		case '/':
	    			js2();
	    			stack_ch.push('/');
	    			break;
	    		case '(':
	    			stack_ch.push('(');
	    			break;
	    		case ')':
	    			js1();
	    			stack_ch.pop();
	    			break;
	    		case '.':
	    			{
	    				js1();
	    				stack_ch.pop();
					}
			}
	}
			printf("%d\n",stack_num.top());
}

你可能感兴趣的:(蓝桥算法训练 表达式计算)