表达式转换问题——读取中缀表达式并生成后缀表达式

中缀表达式,形如1+2,是我们常用的运算表达式,作为自然语言被广泛的使用,但是,在计算机的计算机制中,并不是直接的对这个表达式进行计算,计算有特殊的数据结构对运算表达式进行储存和计算,就是数据结构中常用的堆栈,而其中有一个步骤至关重要,就是将中缀表达式转换为后缀表达式。

众所周知,常用的运算符号有+、-、*、/、(、),但是这些符号在计算的时候有不同的优先级,乘法和除法的优先级高于加法和减法,但是遇到括号内存在表达式的情况,那么就要首先计算括号中的表达式。这就代表,我们在设计程序的时候应当考量这些符号的优先级问题。

在同一级的符号运算中,中缀表达式生成后缀表达式是很简单的。

比如1+2-3,首先输出1,将+弹入堆栈,然后输出2,减号弹入堆栈,最后输出3,到了末尾,将堆栈元素全部弹出。

那么就是123-+.在这个表达式转换中,2和3是后来输出的元素,那么就要匹配后来出现的运算符号,所以运算符的储存数据结构应该满足后入先出的特点,因此我们选用堆栈作为储存符号的数据结构。

但是在1*2+3式子中,采用刚才的同级方式,就不合理了,他会变成123+*,意思变成先2+3再进行乘法,和原来式子表达的意思不符合,那么就要引入优先级。

在这个式子中,乘法的优先级高于加法,所以当遍历到加法的时候,乘法的优先级较高,所以应当直接就弹出乘法,再放入加法,也就是12*然后输出3弹出乘法,也就是12*3+,符合要求。

当式子出现括号时,比如(1+2)*3,应当先计算加法然后计算乘法,左括号直接放入堆栈,当遍历到右括号时,弹出括号内的表达式,所以就是12+3*符合要求。

/************************Stack.h**********************/
#include <iostream>
using namespace std;
typedef char ElementType;
struct Node
{
	ElementType ch;
	int m;
};

#define TRUE 1
#define FALSE 0
#define MAXSIZE 100

class Stack
{
private:
	Node data[MAXSIZE];
	int top;
public: 
	Stack();                          //构造
	~Stack();                         //析构
    void Add(ElementType data);       //添加元素
	void Pop();                       //弹出元素
	bool is_empty();                  //判断是否为空
	bool is_full();                   //判断是否满
	void Fix_Change(ElementType A[],int N); //输出后缀表达式
};

  

/********************Stack.cpp*******************/
#include <iostream>
#include "Stack.h"
using namespace std;

Stack::Stack()                         //构造函数
{
	top=-1;
}


Stack::~Stack()                         //析构函数
{}


bool Stack::is_empty()
{
	if (top==-1)
		return TRUE;
	else 
		return FALSE;
}


bool Stack::is_full()                    //判断是否满
{
	if (top==MAXSIZE-1)
		return TRUE;
	else 
		return FALSE;
}


void Stack::Add(ElementType da)          //添加
{
	if (is_full())
	{
		cout<<"ERROR!"<<endl;
		return;
	}
	else 
	{
		data[++top].ch=da;
		return;
	}
}


void Stack::Pop()                        //弹出
{
	if (is_empty())
	{
		cout<<"ERROR!"<<endl;
		return;
	}
	else 
	{
		cout<<data[top--].ch;
		return;
	}
} 

void Stack::Fix_Change(ElementType A[],int N)
{
	int i=0;
	int m;
	for (i=0;i<N;i++)
	{
		if (A[i]<='9'&&A[i]>='0')
			cout<<A[i];
		else 
		{
			if (A[i]=='(')                         //前括号直接进入
			{
				Add(A[i]);
				data[top].m=3;
			}

			else if (A[i]==')')                    //后括号不放入,弹出
			{
				while (data[top].ch!='(')
				Pop();
				top--;
			}

			else if (A[i]=='*'||A[i]=='/')                             //乘法和除法
			{
				if (top==-1)
				{
					Add(A[i]);
					data[top].m=1;
				}
				else 
				{
					m=1;
					if (m>data[top].m)
						while (top!=-1&&data[top].ch!='(')             //清空栈至括号操作
							Pop();
						Add(A[i]);
						data[top].m=m;
				}
			}

			else if (A[i]=='+'||A[i]=='-')                             //加法和减法
			{
				if (top==-1)
				{
					Add(A[i]);
					data[top].m=2;

				}

				else 
				{
					m=2;
					if (m>data[top].m)
						while (top!=-1&&data[top].ch!='(')
							Pop();
						Add(A[i]);
						data[top].m=m;
				}
			}

			else 
				cout<<"ERROR!"<<endl;
		}
		if (i==N-1)
		{
	    	while (top!=-1)
				Pop();
		}
	}
}

  

/*********************main.cpp**********************/
#include <iostream>
#include "Stack.h"
using namespace std;
int main()
{
	int n;
	int i;
	ElementType *p;
	Stack sk;
	cout<<"Please enter the number of characters:"<<endl;
	cin>>n;
	p=new ElementType[n];
	cout<<"Please enter the elements of the expressions:"<<endl;
	for (i=0;i<n;i++)
		cin>>p[i];
	sk.Fix_Change(p,n);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/Linda-Blog/p/9230440.html
今日推荐