中缀表达式求值(c++)

本文介绍如何使用C++编程实现中缀表达式的求值算法,详细讲解了从中缀表达式转换为后缀表达式的过程,并通过实例展示了计算逻辑。
//环境:vs2010
//expseqstack.h


#ifndef EXPSEQSTACK_H                    //定义头文件
#define EXPSEQSTACK_H
const int StackSize=10;  //10只是示例性的数据,可以根据实际问题具体定义
typedef struct
{
	char op;
	int inputprecedence;
	int stackprecedence;
}DataType1;

template <class T>       //定义模板类SeqStack
class SeqStack
{
public:
    SeqStack( ) ;            //构造函数,栈的初始化
	~SeqStack( );            //析构函数
    void Push(T x);          //将元素x入栈
    T Pop( );                //将栈顶元素弹出
    T GetTop( );	         //取栈顶元素(并不删除)
	bool Empty( );           //判断栈是否为空
private:
    T data[StackSize];      //存放栈元素的数组
    int top;                //栈顶指针,指示栈顶元素在数组中的下标
};
#endif

 

//expseqstack.cpp

//SeqStack.cpp
#include "expseqstack.h"

/*
 * 前置条件:栈不存在
 * 输    入:无
 * 功    能:栈的初始化
 * 输    出:无
 * 后置条件:构造一个空栈
 */

template <class T>
SeqStack<T>::SeqStack( )
{
	top=-1;
}

/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:销毁栈
 * 输    出:无
 * 后置条件:释放栈所占用的存储空间
 */

template <class T>
SeqStack<T>::~SeqStack( )
{

} 

/*
 * 前置条件:栈已存在
 * 输    入:元素值x
 * 功    能:在栈顶插入一个元素x
 * 输    出:如果插入不成功,抛出异常
 * 后置条件:如果插入成功,栈顶增加了一个元素
 */

template <class T> 
void SeqStack<T>::Push(T x)
{
    if (top== StackSize-1) throw "上溢";
    top++;
    data[top]=x;
}

/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:删除栈顶元素
 * 输    出:如果删除成功,返回被删元素值,否则,抛出异常
 * 后置条件:如果删除成功,栈顶减少了一个元素
 */     

template <class T>
T SeqStack<T>::Pop( )
{ 
    T x;
    if (top==-1) throw "下溢";
    x=data[top--];
    return x;
}

/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:读取当前的栈顶元素
 * 输    出:若栈不空,返回当前的栈顶元素值
 * 后置条件:栈不变
 */

template <class T> 
T SeqStack<T>::GetTop( )
{
	if (top!=-1)  
    return data[top];
}

/*
 * 前置条件:栈已存在
 * 输    入:无
 * 功    能:判断栈是否为空
 * 输    出:如果栈为空,返回1,否则,返回0
 * 后置条件:栈不变
 */

template <class T> 
bool SeqStack<T>::Empty( )
{
	if(top==-1) return 1;
	else return 0;
} 

 

//test.cpp

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

#include "expseqstack.cpp"
DataType1 MathOptr(char ch) //为不同的运算符赋值优先级
{
	DataType1 optr;
	optr.op=ch;
	switch(optr.op)
	{
	case'+':
    case'-': optr.inputprecedence=1;
		     optr.stackprecedence=1;
			 break;
    
    case'*':
    case'/': optr.inputprecedence=2;
		     optr.stackprecedence=2;
			 break;
    case'(': optr.inputprecedence=3;
		     optr.stackprecedence=-1;
			 break;
    case')': optr.inputprecedence=0;
		     optr.stackprecedence=0;
			 break;
	}
	return(optr);
}
int isoptr(char ch)//判断输入的字符是否为算术运算符
{
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
		return(1);
	return(0);
}
template <class T>
void Evaluate(SeqStack<T>*OpndStack,DataType1 optr)//计算某一符号的表达式的值,结果进数据栈;
{
	T opnd1,opnd2;
	opnd1=OpndStack->Pop();
	opnd2=OpndStack->Pop();
	switch(optr.op)
	{
	case'+':OpndStack->Push(opnd2+opnd1);
		break;
    case'-':OpndStack->Push(opnd2-opnd1);
		break;
    case'*':OpndStack->Push(opnd2*opnd1);
		break;
    case'/':OpndStack->Push(opnd2/opnd1);
		break;
	}
}
void Infix(char *str)//中缀表达式的求值
{
	int i,k;
	char ch,numstr[10];
	float opnd;
	DataType1 optr,temp;
	SeqStack<float> OpndStack;//运算对象栈
	SeqStack<DataType1> OptrStack;//运算符栈
	k=0;
	ch=str[k];
	while(ch!='=')
		if(isdigit(ch)||ch=='.')//数据处理
		{
			for(i=0;isdigit(ch)||ch=='.';i++)
				{
					numstr[i]=ch;
					k++;
					ch=str[k];
				}
				numstr[i]='\0';
				opnd=atof(numstr);//把字符串转化为浮点数
				OpndStack.Push(opnd);//操作数进栈
		}
		else//运算符处理
		{
			optr=MathOptr(ch);//ch的优先级赋值
			if(ch=='(') 
				{
					OptrStack.Push(optr);
					k++;
					ch=str[k];
				}
			else if(isoptr(ch))
				{
					while(!OptrStack.Empty () && OptrStack.GetTop().stackprecedence>=optr.inputprecedence)
						Evaluate(&OpndStack,OptrStack.Pop());
					OptrStack.Push(optr);
					k++;
					ch=str[k];
				}
			else if(ch==')')
			{
				while(!OptrStack.Empty () && OptrStack.GetTop().op!='(')
					Evaluate(&OpndStack,OptrStack.Pop());
				if(!OptrStack.Empty ())
					temp=OptrStack.Pop();
				k++;
				ch=str[k];
			}
		}//表达式结束
		while(!OptrStack.Empty ())
			Evaluate(&OpndStack,OptrStack.Pop());
		opnd=OpndStack.Pop();
		cout<<"表达式的值为"<<opnd<<endl;
}
void main()
{
	char str[50];
	gets(str);//从stdio流中读取字符串,直至接受到换行符或EOF时停止,
	Infix(str);//中缀表达式的求值
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值