中缀表达式检测并转换后缀表达式,计算后缀表达式的结果

Posted 爵士

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中缀表达式检测并转换后缀表达式,计算后缀表达式的结果相关的知识,希望对你有一定的参考价值。

实现代码如下

#include <iostream>
#include <stack>
#include <ctype.h>
using namespace std;
//这里的数字只能是一位
//扫描表达式是否合法,合法返回0,否则返回非0
int Scanner(const char *str)
{
	stack<char*> s;
	if(str==NULL)
	{
		return -1;
	}
	char *p=(char*)str;
	while(*p!=\'\\0\')
	{
		if(*p==\'(\')//如果是左括号就入栈
		{
			s.push(p);
		}
		else if(*p==\')\')//右括号就获得栈顶符号,并匹配
		{
			if(!s.empty())//栈不为空
			{
				char *t=s.top();//拿到栈顶元素进行匹配
				if(*t==\'(\')//匹配
				{
					s.pop();
				}
			}
		}
		p++;
	}
	if(!s.empty())//最后栈为空匹配失败
	{
		return -1;
	}
	return 0;
}
//返回运算符号的优先级
int GetPriority(char ch)
{
	if(ch==\'+\'||ch==\'-\')
	{
		return 1;
	}
	else if(ch==\'*\'||ch== \'/\')
	{
		return 2;
	}
	else
	{
		return 0;
	}
}
//中缀表达式转换为后缀表达式
int Transform(/*in*/char *src,/*out*/char *dest)
{
	stack<char*> s;
	int i=0;
	if(src==NULL||dest==NULL)
	{
		return -1;
	}
	char *psrc=src;
	while(*psrc!=\'\\0\')
	{
		//if(*psrc>=\'0\'&& *psrc<=\'9\')//如果是数字
		if(isdigit(*psrc))//如果字符是数字时
		{
			dest[i]=*psrc;
			i++;
		}
		else if(*psrc==\'(\')//如果是左括号就进栈
		{
			s.push(psrc);
		}
		else if(*psrc==\')\')//如果是右括号,弹出栈顶元素
		{
			while(!s.empty()&&(*s.top())!=\'(\')
			{
				dest[i]=*s.top();
				i++;
				s.pop();
			}
			s.pop();//弹出左括号
		}
		else if((*psrc==\'+\')||(*psrc==\'-\')||(*psrc==\'*\')||(*psrc==\'/\'))//如果是运算符
		{
			while(!s.empty()&&GetPriority(*s.top())>=GetPriority(*psrc))//比较运算符优先级
			{//若栈顶符号优先级不低
				dest[i]=*s.top();
				i++;
				s.pop();
			}
			s.push(psrc);//栈顶符号优先级低
		}
		else
		{
			cout<<"表达式中有非法字符"<<endl;
			return -1;
		}
		psrc++;
	}
	while(!s.empty())
	{
		dest[i]=*s.top();
		i++;
		s.pop();
	}
	dest[i]=\'\\0\';//最后一个字符以\\0结尾
	return 0;
}
//运算法则
int Arithmetic(int left,int right,char c)
{
	switch(c)
	{
	case \'+\':
		return left+right;
	case \'-\':
		return left-right;
	case \'*\':
		return left*right;
	case \'/\':
		if(right==0)
		{
			return 0;
		}
		else
		{
			return left/right;
		}
	default:
		return 0;
	}
}
//计算后缀表达式的运算结果
//说明此接口将结果返回,不怎么好,可以将结果传出,使用一级指针
//int calculate(char *str,int* out)
int Calculate(char *src)
{
	if(src==NULL)
	{
		return -1;
	}
	stack<int> s;//栈中放入int
	char* psrc=src; 
	int result=0;//表达式计算的结果
	while(*psrc!=\'\\0\')
	{
		if(isdigit(*psrc))//如果字符是数字时
		{
			s.push(*psrc-\'0\');//将数字符号转化为int压入栈中
		}
		else if((*psrc==\'+\')||(*psrc==\'-\')||(*psrc==\'*\')||(*psrc==\'/\'))//如果是符号
		{
			int right=s.top();//拿到左操作数,并弹出
			s.pop();
			int left=s.top();//拿到右操作数,并弹出
			s.pop();
			int re=Arithmetic(left,right,*psrc);
			s.push(re);//将运算结果压入栈中
		}
		else
		{
			cout<<"表达式中有非法字符"<<endl;
			return -1;
		}
		psrc++;
	}
	if(s.size()==1)//栈中只有一个结果时,就是最终运算结果
	{
		result=s.top();
		return result;
		//s.pop();
	}
	else
	{
		cout<<"运算结果不正确"<<endl;
		return -1;
	}
	return result;
}
int main()
{
	char *exp="(2+4)*3-9";
	cout<<"中缀表达式:"<<exp<<endl;
	if(Scanner(exp)!=0)
	{
		printf("表达式匹配失败\\n");
		return -1;
	}
	char newexp[128];
	Transform(exp,newexp);
	cout<<"后缀表达式:"<<newexp<<endl;
	int re=Calculate(newexp);
	cout<<"运算结果为:"<<re<<endl;
	return 0;
}

  

以上是关于中缀表达式检测并转换后缀表达式,计算后缀表达式的结果的主要内容,如果未能解决你的问题,请参考以下文章

中缀表达式转换前\后缀表达式的总结

中缀表达式转后缀表达式并计算

中缀表达式转换为后缀表达式

将中缀表达式转换为后缀表达式

算术表达式的前缀,中缀,后缀相互转换

中缀表达式转换成后缀表达式并求值