中缀表达式转后缀表达式,并计算后缀表达式的值

前言:在下萌新,接触数据结构一月,代码未能完善之处,请多包含。如果同是萌新阅读文章,请理智看待,因为我并不是大佬。但是文章注释很全(鼠标移到图片上点击查看代码,即可看到所有注释),可以看到整个算法的思想,这点或许会帮助到各位萌新朋友。

如果是大佬观摩的话,希望各位大佬走的时候,能留个声音,因为在下太笨,希望得到各位的指点。

中缀表达式转后缀表达式算法思想:

  • (1)遇到操作数,直接加入后缀表达式。
  • (2)遇到界限符,如遇到“(” 直接入栈,遇到 “)”则依次弹出栈内运算符并加入后缀表达式,直到弹出“(”为止。注意的是,“(”不加入后缀表达式。
  • (3)遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止。之后再把当前运算符入栈。

后缀表达式计算算法思想

  • (1)从左往右扫描下一个元素,直到处理完所有元素;
  • (2)若扫描到操作数则将其入栈,并回到(1),否则执行(3);
  • (3)若扫描到运算符则出栈两个栈顶元素,执行相应计算,并将结果压入栈顶,回到(1)。(需要注意的是,在后缀表达式的机算中,先出栈的是右操作数)
    //用栈转换中缀表达式为后缀表达式,并完成计算
    #define MaxSize 10
    typedef struct
    {
    	char data[MaxSize];
    	int top;
    }Sqstack;
    
    void InitStack(S);	//初始化栈
    void Push(S, x);		//入栈
    void Pop(S);			//出栈
    bool StackEmpty(S);	//判空
    
    //用栈转换中缀表达式为后缀表达式
    void Stack_expression(char a[], char b[], int length)//a是要转换的中缀表达式,b是完成后的后缀表达式,length是中缀表达式的长度。
    {
    	Sqstack Symbol;										//定义一个运算符栈
    	int n = 0;
    	for (int i = 0; i < length; i++)					//遍历中缀表达式a,会遇到3种情况,遇到操作数,界限符和运算符
    	{
    		//遇到操作数,直接加入后缀表达式
    		if (a[i] >= 48 && a[i] <= 57)					
    		{
    			b[n] = a[i];
    			n++;
    		}
    		//遇到运算符,优先级高的运算符出栈加入后缀表达式
    		if (a[i] == '+' || a[i] == '-' || a[i] == '*' || a[i] == '/')
    		{
    			if (StackEmpty(Symbol))						//如果运算符栈为空,直接入栈
    				Push(Symbol, a[i]);
    			else										//不为空,则与栈内运算符逐个比较
    			{
    				int j = 0;
    				for (j = Symbol.top; j > -1; j--)		//从栈顶往下依次比较
    				{
    					if (Priority(a[i], Symbol.data[j]))	//如果当前运算符优先级高于栈顶元素,则将其压入栈中,成为新的栈顶元素。另外Priority()是判断运算符优先级的函数。
    					{
    						Push(Symbol, a[i]);				
    						break;							//这里的break是跳出for循环,不是跳出if
    					}
    					else								//当前运算符优先级低于或等同于栈顶元素,则弹出栈顶元素,加入后缀表达式
    					{
    						b[n] = Symbol.data[j];
    						n++;
    						Pop(Symbol);					//这里相当于从栈中删除栈顶元素,因为它已经加入后缀式了
    					}
    				}
    				if (j == -1)							//遍历到栈底,所有比当前运算符优先级高的元素都出栈后,把当前运算符入栈
    					Push(Symbol, a[i]);
    			}
    		}
    		//遇到界限符
    		if (a[i] == '(' || a[i] == '[' || a[i] == '{')	//遇到左括号直接将其入栈
    			Push(Symbol, a[i]);
    		if (a[i] == ')')								//遇到右括号,将栈内元素依次吐出
    		{
    			while (Symbol.top != '(')					//直到遇到左括号前,依次弹出栈内运算符加入后缀式
    			{
    				b[n] = Symbol.data[Symbol.top];	
    				n++;
    				Symbol.top--;
    			}
    		}
    		if (a[i] == ']')
    		{
    			while (Symbol.data[Symbol.top] != '[')
    			{
    				b[n] = Symbol.data[Symbol.top];
    				n++;
    				Symbol.top--;
    			}
    		}
    		if (a[i] == '}')
    		{
    			while (Symbol.data[Symbol.top] != '{')
    			{
    				b[n] = Symbol.data[Symbol.top];
    				n++;
    				Symbol.top--;
    			}
    		}
    	}
    }
    
    //后缀表达式的计算
    void Operation(char b[], int length)
    {
    	Sqstack Figure;			//定义一个操作数栈
    	for (int i = 0; i < length; i++)
    	{
    		//如果是操作数直接入栈
    		if (b[i] >= 48 && b[i] <= 57)
    			Push(Figure, b[i]);
    		//如果是运算符,则弹出操作数栈栈顶两个元素参与运算,先出栈的是右操作数
    		else
    		{
    			char x = Figure.data[Figure.top];
    			char y = Figure.data[Figure.top - 1];
    			Figure.top = Figure.top - 2;
    			char s = Calculate(x, y, b[i]);				//Calculate()是计算函数
    			Push(Figure, s);							//将结果压入操作数栈
    		}
    	}
    	int final_result = atoi(Figure.data[Figure.top]);//最终结果即是栈底元素,atoi()是字符串转整型函数
    }
    //这里有两个函数没有实现
    //bool Priority(a[i], Symbol.data[j])  比较运算符优先级函数
    //char Calculate(x, y, b[i])		   计算操作数函数

    最终结果即是操作数栈中最后一个元素。

 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值