表达式求值(中缀表达式->后缀表达式)

题目:在一个表达式中,只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,请求出表达式的值。(“/”用整数除法)。

将中缀表达式转化成后缀表达式,一边转化,一边计算。

基本思路
读取完字符串之后,扫描一遍,扫描一遍后,运算也同时结束,过程中将中缀表达式转化成后缀表达式,一边转化,一边计算。
1.如果碰到了数字,开始往数字栈放数字(考虑多位数情况)
2.如果碰到了 “(” 直接入符号栈
3.如果碰到了运算符,如果其优先级大于符号栈顶元素优先级,入栈;
否则,先计算符号栈顶元素和数字栈顶两元素的运算结果,并将结果入栈
(特别的,如果数字栈内元素不足2,那么不论哪一种运算符都要直接入栈)
4.如果碰到了 “)” 开始从两个栈往外提取元素,进行计算,直到符号栈顶元素是 “(” ,计算结束后要把 “(” 也取出,表示这一对括号内的表达式已经计算成一个结果了
5.特别的,“^”的优先级要大于 “*” 和 “/” (比较723和7 ^23的区别)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

int IfNum(char ch)
{   
    if(ch<='9'&&ch>='0')   
    {
	return 1;  
    }
    return 0;
}

int Calculate(int a,char ch,int b)
{
    if(ch=='*')
    {
        return a*b;
    }
    else if(ch=='/')
    {
        return a/b;
    }
    else if(ch=='-')
    {
        return a-b;
    }
    else if(ch=='+')
    {
        return a+b;
    }
    else
    {
        return pow(a,b);
    }
}

int Comparechar(char a,char b)
{
     int x = 0; //a的优先级 
     int y = 0; //b的优先级 
 
     if(a == '+' || a == '-')
     {
          x=1;
     }
     else if(a=='*'|| a=='/')
     {
          x=2;
     }
     else if(a=='^')
     {
          x=3;
     }
     else if(a=='(')
     {
          x=4;
     }
 
     if(b=='+'||b=='-')
     {
          y=1;
     }
     else if(b=='*'||b=='/')
     {
          y=2;
     }
     else if(b=='^')
     {
          y=3;
     }
     else if(b=='(')
     {
          y=4;
     }
 
     if(x > y)
     {
         return 1;
     }
     return 0;
}

int main()
{
	char s[310];//主串 
	int num[310];//数字栈 
	char ch[310];//运算符栈 

	gets(s);
	int topn, topc;
	topn = 0;//数字栈的栈顶 
	topc = 0;//符号栈的栈顶 

	for (int i = 0; i < 310; i++)
	{
		num[i] = 0;
		ch[i] = '0';
	}

	int i = 0;
	while (i < strlen(s))
	{
		if (IfNum(s[i]))
		{
			while (IfNum(s[i]))
			{
				num[topn] = num[topn] * 10 + s[i++] - '0';
			}
			topn++;
			continue;
		}
		else
		{
			if (s[i] == '(')			
			{
				ch[topc++] = s[i];
			}
			else if (s[i] == ')') 
			{
				while (ch[topc - 1] != '(')
				{

					num[topn - 2] = Calculate(num[topn - 2], ch[topc - 1], num[topn - 1]);
					num[topn - 1] = 0;//数字栈顶元素用完之后要清零,否则影响之后的运算 
					topc--;
					topn--;
				}
				topc--;//计算完括号内的式子后将左括号移除 
			}
	       else 
			{
				if (topc == 0)//如果符号栈为空,则直接入栈 
				{
					ch[topc++] = s[i];
				}
				else if (Comparechar(s[i], ch[topc - 1])) 
				{
					//如果是当前运算符优先级比栈顶运算符优先级大 直接入栈 
					ch[topc++] = s[i];
				}
				else  
				{
				    //当前运算符优先级比栈顶运算符优先级小 
					while (!Comparechar(s[i], ch[topc - 1])) 
					{
						if (ch[topc - 1] == '(')
						{
							break;
						}
						num[topn - 2] = Calculate(num[topn - 2], ch[topc - 1], num[topn - 1]); 
						num[topn - 1] = 0;
						topc--;
						topn--;

						if (topc == 0)
						{
							break;
						}
					}
					ch[topc++] = s[i];//计算完成之后,运算符进栈
				}
			}
		}
		i++;
	}
	
    while (topn != 1 && topc > 0)  //在遍历整个字符串之后如果两个栈还有数据
	{
		num[topn - 2] = Calculate(num[topn - 2], ch[topc - 1], num[topn - 1]);
		topn--;
		topc--;
	}
	printf("%d", num[0]);//一旦数字栈里只剩一个数字 或者运算符栈没有符号了 那就停止计算 
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值