中缀表达式简单算术表达式的C++求解.docx

上传人:b****8 文档编号:9526027 上传时间:2023-02-05 格式:DOCX 页数:21 大小:64.96KB
下载 相关 举报
中缀表达式简单算术表达式的C++求解.docx_第1页
第1页 / 共21页
中缀表达式简单算术表达式的C++求解.docx_第2页
第2页 / 共21页
中缀表达式简单算术表达式的C++求解.docx_第3页
第3页 / 共21页
中缀表达式简单算术表达式的C++求解.docx_第4页
第4页 / 共21页
中缀表达式简单算术表达式的C++求解.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

中缀表达式简单算术表达式的C++求解.docx

《中缀表达式简单算术表达式的C++求解.docx》由会员分享,可在线阅读,更多相关《中缀表达式简单算术表达式的C++求解.docx(21页珍藏版)》请在冰豆网上搜索。

中缀表达式简单算术表达式的C++求解.docx

中缀表达式简单算术表达式的C++求解

计算机软件技术基础作业一说明

中缀表达式简单算术表达式的求解 

1、源程序见包内,经检测可以在MSVC++6.0中正确运行,可以输入800个符号内任意长度的中缀表达式,并拥有了判错功能;

2、本题通过构造堆栈实现中缀表达式的运算;

3、算法思路:

用模板实现的链式结构堆栈类并且实现类模板成员函数,专门定义算法函数charPrecede(charch1,charch2)进行运算,判别函数intOperator(charch)判别运算符号是否正确,。

运算时根据优先级的大小进行:

相等则消去括号;下一个大则压入下一个符号;前面大则先将前面数字算好,再将答案压入数字栈中。

最后将判错功能的算法加入程序中。

4、数据结构设计说明

本程序使用了堆栈的方法,同时采用了数组形式作为数据结构。

5、程序流程说明

6、程序运行的验证过程

(1)正常运行

(2)错误一

(3)错误二

(4)错误三

(5)错误四

(6)错误五

(7)错误六

(8)错误八

7、效果分析:

将数据压入一个堆栈中,分别读取数字符和运算符,中缀表达式由键盘输入,以回车键结束。

如:

3*((4+6)-(5-2)^3)。

由于C++不能读取’\n’,所以该题目只能在读取到’\0’时算到最终结果。

程序给出算术表达式的精确结果,同时给出错误之处!

比如中缀表达式中不能包含多余的空格;中缀表达式中的运算数由{0,1,…,8,9}中的单个数字组成;中缀表达式中只包含5种2目运算符:

+,-,*,/,^及两种优先级运算符“(”和“)”等等。

8、原创内容及体会

刚刚编写程序时,我按照老师课件进行。

但是遇到了不可解决的麻烦,其源程序见下:

(请老师指点,邮箱:

****************)

#include

#include

#include

#include

usingnamespacestd;

template

voidinitStack(T*s,intm,int*top)

{

s=newT(m);//动态申请容量为m的存储空间

*top=0;//栈顶指针

return;//当前分配的栈空间

}

template

voidpush(T*s,intm,int*top,Tx)

{

if(*top==m)

{cout<<"Stackoverflow!

"<

*top=*top+1;//序号指针递增

s[*top-1]=x;//入栈

return;

}

template

Tpop(T*s,intm,int*top)

{

Ty;

if(*top==0)

{cout<<"Stackunderflow!

"<

y=s[*top-1];//退栈

*top=*top-1;//序号指针递减

return(y);//返回栈顶元素

}

intOperate(inta,chare,intb)//运算操作

{

intc;

switch(e)

{

case'+':

{c=a+b;break;}

case'-':

{c=a-b;break;}

case'*':

{c=a*b;break;}

case'/':

{c=a/b;break;}

case'^':

{c=pow(a,b);break;}

default:

printf("error\n");

}

returnc;

}

charPrecede(charch1,charch2)

{

charch;

switch(ch1)

{

case'+':

case'-':

{

switch(ch2)

{

case'+':

case'-':

case')':

case'\n':

ch='>';

break;

case'*':

case'/':

case'^':

case'(':

ch='<';break;

}

break;

}

case'*':

case'/':

{

if(ch2=='('||ch2=='^')

ch='<';

else

ch='>';

break;

}

case'^':

{

if(ch2=='(')

ch='<';

else

ch='>';

break;

}

case'(':

{

if(ch2==')')

ch='=';

else

ch='<';

break;

}

case')':

{

ch='>';

break;

}

case'\n':

{

if(ch2=='\n')

ch='=';

else

ch='<';

break;

}

}

return(ch);

}

template

intEvaluateExpression()

{

charc,theta;inta,b,answer;T:

OPTR,OPND;

initStack(OPTR);push(OPTR,'\n');

initStack(OPND);c=getchar();

while(c!

='\n'||GetTop(OPTR)!

='\n'){//边输入边处理

if(!

In(c,OP)){push(OPND,c);c=getchar();}

//不是运算符则进栈,In(c,OP)判断c是否是运算符

else

switch(Precede(GetTop(OPTR),c))

{

case<:

//新输入的算符c优先级高,c进栈

push(OPTR,c);c=getchar();break;

case=:

//脱括号并接收下一字符

pop(OPTR,x);c=getchar();break;

case>:

//新输入的算符c优先级低(栈顶算符优先级高)

//出栈并将运算结果入栈OPND

pop(OPTR,theta);

pop(OPND,b);Pop(OPND,a);

push(OPND,Operate(a,theta,b));

break;

}//switch

}//while

answer=GetTop(OPND);

cout<

return0;

}

template

intmain()

{

EvaluateExpression();

return0;

}

此程序运行过程中,编译没错,可一到连接就出现这个问题:

1unresolvedexternals!

再三思考,我放弃了这个方案,通过XX搜索,我找到一个以#结束,不能乘方运算,没有详细错误提示的程序,其思路与老师的方案大致相同,只不过采用了数组的形式,不过都对中缀表达式的长度没有确定的要求。

经过一整天的编辑,我终于完成并调试成功了这个程序,心里充满了成功的喜悦感!

以下是我的最终程序(与软件1.cpp内容相同):

#include"iostream.h"

#include"stdlib.h"

#include"math.h"

#include"time.h"

#defineTRUE1

#defineFALSE0

#defineERROR-1

typedefintStatus;

 

//用模板实现的链式结构堆栈类

template

classstack{

private:

structlink{

Tdata;//结点数据域

link*next;//下一结点指针

link(TData,link*Next){//结构体构造函数

data=Data;

next=Next;

}

}*head;//堆栈顶指针

public:

stack();//构造函数(初始化栈)

~stack();//析构函数(销毁栈)

voidpush(TData);//压栈操作

Tgettop()const;//取栈顶元素

Tpop();//出栈操作

Tgetvalue(intindex);//返回栈底开始第INDEX个栈中值

voidtraverse(intn);//遍历栈N个数换行

intempty();//判断栈是否为空,1是,0非

intsizeofstack();//返回栈的大小

voidclear();//清空栈

};

 

//类模板成员函数的实现

templatestack:

:

stack()//构造函数

{

head=0;

}

templatestack:

:

~stack()//析构函数

{

link*cursor=head;

while(head)

{

cursor=cursor->next;

deletehead;

head=cursor;

}

}

templatevoidstack:

:

push(TData)//压栈操作

{

head=newlink(Data,head);

}

templateTstack:

:

gettop()const//取栈顶元素

{

returnhead->data;

}

templateTstack:

:

pop()//出栈操作

{

if(head==0)return0;

Tresult=head->data;

link*oldhead=head;

head=head->next;

deleteoldhead;

returnresult;

}

templateTstack:

:

getvalue(intindex)//返回栈底开始第INDEX个栈中值

{

link*cursor=head;

inti=1;

intstacklen=sizeofstack();

if(index<=0||index>stacklen)return0;

while(i<=(stacklen-index))

{

cursor=cursor->next;

i++;

}

returncursor->data;

}

templatevoidstack:

:

traverse(intn)//遍历栈

{

link*cursor=head;

intiEnterSign=1;//换行标识

while(cursor)

{

cout<data<<"";

if(iEnterSign%n==0)cout<

cursor=cursor->next;

iEnterSign++;

}

if((iEnterSign-1)%n!

=0)cout<

}

templateintstack:

:

empty()//判断栈是否为空,1是,0非

{

returnhead==0?

1:

0;

}

templateintstack:

:

sizeofstack()//返回栈的大小

{

intsize=0;

link*cursor=head;

while(cursor)

{

cursor=cursor->next;

size++;

}

returnsize;

}

templatevoidstack:

:

clear()//清空栈

{

link*cursor=head;

while(cursor&&cursor->next)

{

cursor=cursor->next;

deletehead;

head=cursor;

}

}

intOperator(charch)

{

if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^'||ch=='('||ch==')'||ch=='\r')

return(TRUE);

else

return(FALSE);

}

charPrecede(charch1,charch2)

{

charch;

switch(ch1)

{

case'+':

case'-':

{

switch(ch2)

{

case'+':

case'-':

case')':

case'\r':

case'#':

ch='>';

break;

case'*':

case'/':

case'^':

case'(':

ch='<';break;

}

break;

}

case'*':

case'/':

{

if(ch2=='(')

ch='<';

elseif(ch2=='^')

ch='<';

else

ch='>';

break;

}

case'^':

{

if(ch2=='(')

ch='<';

else

ch='>';

break;

}

case'(':

{

if(ch2==')')

ch='=';

else

ch='<';

break;

}

case')':

{

ch='>';

break;

}

case'\r':

case'#':

{

if(ch2=='\r'||ch2=='#')

ch='=';

else

ch='<';

break;

}

}

return(ch);

}

doublecalc(doublex,charch,doubley)

{

doublez;

switch(ch)

{

case'+':

z=x+y;break;

case'-':

z=x-y;break;

case'*':

z=x*y;break;

case'/':

z=x/y;break;

case'^':

z=pow(x,y);break;

}

return(z);

}

doublemiddexpression(char*exp)//求解中缀表达式

{

stack*opnd=new(stack);

stack*optr=new(stack);

charch=*exp;

doublex=0,y,z;

doubleresult;

optr->push('#');

while(ch!

='\0')

{

//cout<

if(ch>='0'&&ch<='9')

{

x=ch-48;

opnd->push(x);

ch=*++exp;

if(ch>='0'&&ch<='9')

{

cout<<"不符合要求,运算数必须是0~9之间的数"<

exit(0);

}

}

elseif(Operator(ch))

{

switch(Precede(optr->gettop(),ch))

{

case'<':

//栈顶元素优先权低

optr->push(ch);

ch=*++exp;

if(ch=='\0')

{

cout<<"表达式错误,操作符不能用作结尾!

"<

exit(0);

}

break;

case'=':

//脱括号并接收下一字符

optr->pop();

ch=*++exp;

if(ch>='0'&&ch<='9')

{

cout<<"不符合要求,右括号后没有运算符!

"<

exit(0);

}

break;

case'>':

//退栈并将运算结果入栈

if(opnd->sizeofstack()<2)

{

cout<<"数字不够,表达式不合法!

"<

exit(0);

}

x=opnd->pop();

y=opnd->pop();

z=calc(y,optr->pop(),x);

opnd->push(z);

//cout<

x=0;

break;

}

}

elseif(ch!

='\0'&&!

Operator(ch)&&ch!

='')

{

cout<<"不符合要求,只能进行:

+,-,*,/,^,(,)运算!

"<

exit(0);

}

elseif(ch!

='\0'&&!

Operator(ch)&&ch=='')

{

cout<<"不符合要求,中缀表达式中不允许包含多余的空格!

"<

exit(0);

}

else

{

cout<<"输入不合法!

"<

exit(0);

}

if(ch=='\0')

{

while(opnd->sizeofstack()>=2)

{

if(optr->gettop()=='(')

{

cout<<"表达式中的'('没有')'与之相对应!

"<

exit(0);

}

switch(Precede(optr->gettop(),'#'))

{

case'<':

//栈顶元素优先权低

optr->push(ch);

ch=*++exp;

break;

case'=':

//脱括号并接收下一字符

optr->pop();

ch=*++exp;

break;

case'>':

//退栈并将运算结果入栈

x=opnd->pop();

y=opnd->pop();

z=calc(y,optr->pop(),x);

opnd->push(z);

//cout<

x=0;

break;

}

}

}

}

result=(opnd->pop());

return(result);

}

voidmain(void)//程序入口函数

{

charexp[800];

cout<<"请输入中缀表达式(以回车键结束):

"<

cin.getline(exp,800);

cout<

}整个程序化费了我将近两整天的功夫,而且到现在我编的第一个程序还不知道错在了哪里,恳求老师的邮件指导,在此不甚感激。

本次试验让我回顾了C++的编程内容,初步掌握了堆栈的使用,让我受益匪浅~~~~

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 思想汇报心得体会

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1