数据结构简单表达式求解的实现.docx
《数据结构简单表达式求解的实现.docx》由会员分享,可在线阅读,更多相关《数据结构简单表达式求解的实现.docx(13页珍藏版)》请在冰豆网上搜索。
数据结构简单表达式求解的实现
实验报告
课程名称数据结构实验报告
题目名称简单表达式求解的实现
学生学院应用数学学院
专业班级信息安全
(1)班
学号
学生姓名
指导教师
简单表达式求解的实现
目录
一、题目要求2
二、程序设计原理2
三、程序功能展示2
四、主要程序思路4
五、程序的对表达式的判断功能12
六、待解决的问题14
一、题目要求
1、内容要求:
1)界面输入表达式;
2)单的表达式运算结果;
3)栈实现。
2、关键技术:
1)editbox的输入值跟定义的变量之间的数据交换;
2)得到了输入的字符串,怎么去把字符串转成可以运算的表达式;
3)用堆栈实现表示的求解;
4)输出。
二、程序设计原理
1、设置OPRT栈和OPND栈,把表达式从左往右分别压入对应栈。
2、对操作符设置优先级,操作符入栈时与栈顶元素进行优先级比较。
相等则栈顶元素出栈;小于则入栈;大于则栈顶操作符出栈,与OPRT栈弹出的2个操作数完成运算并把结果压入OPRT栈。
3、重复上面的两个步骤,直到表达式全部入栈,最后OPRT栈剩下一项,即为表达式求解的结果。
三、程序功能展示
程序界面:
在输入框中输入表达式,按“确定”按钮,即可在下面的文本框中输出结果。
点击“重置”按钮,则清空两个文本框的内容。
点击“退出”按钮,则退出程序。
输入任意的简单表达式(+、-、*、/)即可求解。
四、主要程序思路
1、创建栈。
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefstructTagStack{
int*base;
int*top;
intstacksize;
}
Stack_S;
classCStack{
public:
CStack();
~CStack();
voidInitStack(Stack_S&S);
boolGetTop(Stack_SS,int&e);
boolPush(Stack_S&S,inte);
boolPop(Stack_S&S,int&e);
}
//初始化栈
voidCStack:
:
InitStack(Stack_S&S){
S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!
S.base)
exit(-1);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE; //空间初始分配
}
//获取栈顶元素
boolCStack:
:
GetTop(Stack_SS,int&e){
if(S.top==S.base)
returnfalse;
e=*(S.top-1);
returntrue;
}
//压栈
boolCStack:
:
Push(Stack_S&S,inte){
if((S.top-S.base)>=S.stacksize){ //空间不够,重新分配{
S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));
if(!
S.base)
exit(-1);
S.top=S.base+S.stacksize; //防止S.base地址可能变更的情况
S.stacksize+=STACKINCREMENT;
}
*S.top++=e; //S.top自增
returntrue;
}
//弹栈
boolCStack:
:
Pop(Stack_S&S,int&e){
if(S.top==S.base)
returnfalse;
e=*--S.top; //S.top自减
returntrue;
}
2、设定运算符之间的优先关系。
为实现运算符优先算法,可以使用两个工作栈。
一个称作OPTR,用以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。
算法的基本思想是:
1)首先置操作数栈为空栈,表达式起始符#为运算符栈的栈底元素;
2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕。
实现代码:
charCbiaodashiDlg:
:
Priority(chary,charx){
charpriority='<';
switch(x){
case'*':
case'/':
if(y==')'||y=='*'||y=='/')
priority='>';
break;
case'+':
case'-':
if(y==')'||y=='+'||y=='-'||y=='*'||y=='/')
priority='>';
break;
case'(':
break;
case')':
if(y=='(')
priority='=';
else
priority='>';
break;
case'#';
if(y=='#')
priority='=';
else
priority='>';
break;
default:
priority='E';
}
returnpriority;
}
3、定义合法操作符。
“+”、“-”、“*”、“/”、“(”、“)”、“#”这七个操作符为合法操作符,在合法操作符之外的字符,定义为非法字符。
实现代码:
boolCbiaodashiDlg:
:
isopr(chara){
switch(a){
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':
returntrue;
default:
returnfalse:
}
}
4、定义合法操作数。
操作数为整数或小数,排除其他字符的输入。
实现代码:
boolCbiaodashiDlg:
:
isopr(chara){
switch(a){
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
case'0':
case'.':
returntrue;
default:
returnfalse:
}
}
5、运算符实现运算功能。
实现代码:
floatCbiaodashiDlg:
:
operate(floata,charo,floatb){
floats;
switch(o){
case'+':
s=a+b;
break;
case"-":
s=a-b;
break;
case'*':
s=a*b;
break;
case'/':
s=a/b;
break;
default:
s=0;
break;
}
returns;
}
6、输入表达式串后的处理与求解。
实现代码:
floatCbiaodashiDlg:
:
Var(char*ch){
TStackopr;
TStackopn;
opr.push('#');
stringstr="";
while(*ch!
=NULL){
if(isopr(*ch)){
if(!
str.empty()){
constchar*p=str.c_str();
opn.push(atof(p));
}
switch(priority(opr.gettop(),*ch)){
case'<':
opr.push(*ch);
if(*ch!
='#')
ch++;
break;
case'=':
opr.pop();
ch++;
break;
case'>':
floatb=opn.pop();
floata=opn.pop();
opn.push(operate(a,opr.pop(),b));
break;
}
str="";
}
else
if(isopn(*ch)){
str=str.append(1,*ch);
ch++;
}
else
ch++;
}
returnopn.gettop();
}
7、MFC中各控件的联系。
先将文本框输入的表达式关联到m_biaodashi中,m_biaodashi为CString变量。
然后在表达式串后添加#号,这样在文本框输入表达式时可以不用输入#号。
m_result为float变量,将结果输出到运算结果的文本框中,并且把#号删去,不显示在文本框中,运算结束。
实现代码:
voidCbiaodashiDlg:
:
OnBnClickedOk(){
UpdateData(ture);
m_biaodashi.Append(L"#");
char*ch=cs2ca(m_biaodashi);
m_result=var(ch);
m_biaodashi.remove('#');
CStringstr;
str.Format(L"%s=%f",m_biaodashi,m_result);
}
五、程序的对表达式的判断功能
1)当第一位不是数字时,提示错误。
2)当表达式中间出现空格时,提示错误。
3)当表达式中输入了中文的括号时,提示错误。
4)当表达式中出现非法字符(符号)时,提示错误。
5)当表达式中出现非法字符(字母)时,提示错误。
6)当表达式中的括号不完整时,提示出错。
六、待解决的问题
1、输入的表达式中,如果第一个数据是负数,如“-1+5”,会提示错误。
2、连续多个运算符,如“5+(-1)”,会提示错误。
3、其他规范的表达式也会提示错误,如“08+0005”、“3/0.0”等。