当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 后缀表达式求值及校验

VC++
用 auto_ptr 类模板帮助动态内存管理
走近 STL
一步一步学STL标准模板库
使用 <multimap> 库创建重复键关联容器
使用 <map> 库创建关联容器
用 vectors 改进内存的再分配
用函数模板实现和优化抽象操作
STL 字符串类与 UNICODE 及其它......
如何在Dll中导出STL类
再谈“在STL列表(Lists)中插入不同类型的对象”
使用::std::vector<>作为管理动态数组的优先选择
三种常见中文内码的转换方法
JNI 中文处理问题小结
构建 GB2312 汉字库的 unicode 码表
正则表达式简介
在非MFC程序中引用CString
UTF-8与GB2312之间的互换
宽字符标量L"xx"在VC6.0/7.0和GNU g++中的不同实现
用VC++设计语法编辑器
C语言中对时间和日期的处理

VC++ 中的 后缀表达式求值及校验


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 145 ::
收藏到网摘: n/a

后缀表达式求值及校验

作者:吴登荣

下载源代码

摘要:

  本程序是一个完整的后缀表达式计算,主要用栈的操作实现,本程序封装了CStack类实现栈的操作,本程序最大的特色在于运用动态监视表达式的算法对表达式进行数据校验,对一切合法的表达式进行计算,检验出所有任何非法表达式并提示。

关键字:后缀表达式,校验

题目:后缀表达式求值。

要求:输入后缀表达式,输入为整数和四则运算,输出计算结果。

例如

  输入:2 3 * 1 -
  输出:5
  分析:2*3-1=5

  输入:1 2 + 5 4 * 3 - * 6 -
  输出:45
  分析:(1+2)*(5*4-3)-6=45    

算法分析

  后缀表达式相对于普通的表达式来说,起优点在于不需要括号。所以方便的计算机的处理,通常对于后缀表达式才用栈的数据结果来实现,从左往右扫描表达式,如果遇到的是数字,则把数字压入栈中;若遇到的是运算符号,则提取栈的的2个元素进行计算,讲计算结果压栈,若最后栈内只剩下一个数字,这就是后缀表达式的计算结果。在此基础上,考虑到对后缀表达式的校验,根据后缀表达式计算的特性,编写了一些函数,对后缀表达式进行校验,应该可以对任何错误的后缀表达式都能校验出来并提示出错,在程序中设置了一些状态,一旦出现了错误状态,立刻停止计算过程,立即报错。

总体设计

  编程环境是VC6.0,新建MFC工程,选择为对话框方式,由于表达式是通过一个文本框输入的,所以在程序中,一定有一个全局函数把字符数字转化为整型的数字。最主要的那个函数也就是计算那个函数,具体详细见下面的OnCalculate()函数或者源代码。本程序采用了栈的数据结构,所以自定义一个CStack类,类的定义,以及实现部分代码可以见下面代码。为了完成校验,另外写了一个Function.h,在里面定义了check函数,检验输入表达式是否含有非法数据,trimblank函数,去除表达式中多余的空格,getop函数,取得表达式中运算符号的个数,具体见源代码。在主函数中,检验的思想是首先判断表达式中时候含有非法字符,若没有,则进一步判断表达式中的的数字个数与符号个数时候否满足“数字个数-1=符号个数”,若满足,则在计算过程中监测在遇到运算符号的时候时候会出现栈内元素小于2个的情况,这一步很重要,在每次计算时都检查当时的条件是否能计算,一旦错误,立刻break,这样即使有错误的输入,WINDOWS也不会报错而导致程序异常结束,即动态的实现了跟踪表达式的计算机,最后,检查一下压栈次数和出栈次数是否满足某一公式(具体我忘记了,自己推一下)就可以判断表达式是否合法。

类CStack的定义:

class CStack
{
private:
int num[100];//栈内元素的存放
int sum;//栈里数据的个数
int flag;//非法操作判断位
int popcount;//记录POP次数
int pushcount;//记录PUSH次数
public:
CStack();
int getflag();//提取非法操作判断位编码 /> int getsum();/> void setflag(int);
int getcount();//通过popcount,pushcount计算返回表达式中的数字的个数
void Pop();//出栈操作
void Push(int temp);//入栈操作
int Top();//返回栈顶元素
virtual ~CStack();
};
类CStack的实现:
 
CStack::CStack(){ for(int i=0;i<=50;i++)	num[i]=0; sum=0; flag=1;//假设所有操作均合法 popcount=0; pushcount=0;} int CStack::getflag(){ return flag;}int CStack::getsum(){ return sum;}void CStack::setflag(int tempflag){	flag=tempflag;}int CStack::getcount(){	return (pushcount*2-popcount)/2;}void CStack::Pop(){	if(sum>=1)//判断是否非法操作	{	num[sum]=0;	sum--;	popcount++;	}	else	{	flag=0;	}}void CStack::Push(int temp){	sum++;	num[sum]=temp;	pushcount++;}int CStack::Top(){	if(sum>=1)//判断是否非法操作	{	return num[sum];	}	else	{	flag=0;	}} 

主程序,这里完成了计算,以及对表达式检验的全部过程:

void CB05031126Dlg::OnCalculate() {	// TODO: Add your control notification handler c