数据结构,用逆波兰表达式求四则混合运算练习题的值,使用C/C++

请输入关键词:
逆波兰表达式
  逆波兰表达式 rpn(Reverse Polish Notation)
  逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:
  正常的表达式 逆波兰表达式
  a+b ---& a,b,+
  a+(b-c) ---& a,b,c,-,+
  a+(b-c)*d ---& a,d,b,c,-,*,+
  a=1+3 ---& a=1,3 +
  http=(smtp+http+telnet)/1024 写成什么呢?
  http=smtp,http,telnet,+,+,1024,/
  逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)*(c+d)转换为ab+cd+*
  它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:
  如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。
  将一个普通的中序表达式转换为逆波兰表达式的一般算法是:
  (1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
  (2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
  (3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
  (4)如果不是数字,该字符则是运算符,此时需比较优先关系。
  做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优先级低于当前运算符,将该字符入栈。
  (5)重复上述操作(3)-(4)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
  下面是程序化算法流程:
  1、建立运算符栈stackOperator用于运算符的存储,压入'\0'。
  2、预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号) 。
  3、顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接输出该数字;如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。
  4、若当前运算符为'(',直接入栈;
  若为')',出栈并顺序输出运算符直到遇到第一个'(',遇到的第一个'('出栈但不输出;
  若为其它,比较stackOperator栈顶元素与当前元素的优先级:
  如果 栈顶元素 &= 当前元素,出栈并顺序输出运算符直到 栈顶元素 & 当前元素,然后当前元素入栈;
  如果 栈顶元素 & 当前元素,直接入栈。
  5、重复第3点直到表达式扫描完毕。
  6、顺序出栈并输出运算符直到栈顶元素为'\0'。
  各运算符及符号优先级:
  '\0': -1
  ')': 1
  '(': 2
  '+'、'-': 3
  '*'、'/'、'%': 4
  '^': 5
  其它: 0
  参考程序:/terrorist_/blog/static/  
了一道计算逆波兰表达式的题,用堆栈目如下: 描述 逆波兰表达式是一种把运术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式 输出为一行,表达式的值。 可直接("%f\n", v)输出表达式的值v。 例子数据存储方式,就是栈。你既...
来自: - 最后更新于:
逆波兰式.还有就是w3eval这个算术表达式/// Reverse Polish Notation /// 算术逆波兰表达式.生成. /// /summary /// param 后缀式了. } /// summary /// 算术逆波兰表达式计算. /// /0; } } /// summary /// 规范化逆波兰表达式. /// /summary /// param name="s" /...
来自: - 最后更新于:
转化为逆波兰,不过转化为逆波兰似乎中缀表达式的值,没必要转逆波兰了,逆波兰一可能产生的表达式。 我在另外一[i] != '=';i++ ) //输入"="代表表达式结束 { if( a[i行时放出的表达式有错误。 求解接计算中缀表达式的值。 谢谢...
来自: - 最后更新于:
波兰表达式(前缀),而不是逆波兰(后缀),比如:原表达式(中缀)!A && !B && !C || D && !E波兰表达式(前缀)+ * * * ~ A ~ B ~ C * D ~ E如上式所示的逻辑表达式可能有逻辑运算中,波兰表达式的好处是,如据表达式的二叉树 ,先序遍历(波兰表达式),后序遍历(逆波兰表达式) 试试用...
来自: - 最后更新于:
目: ◆3.21③ 假设表达式由单字母变形式 且书写正确的表达式转换为逆波兰式(char *e); /* 返回表达式e的逆波兰式 */ Stack是一个(char *e) /* 返回表达式e的逆波兰式 */ { char m= 0 ; char表达式是没有问题,不过有一些表达式...
来自: - 最后更新于:
例如:求算式3*(7-2)的值。要转化为逆波兰式 372-* 再按逆波兰式进栈,碰再入栈。。。。。 用逆波兰符号法表示,用栈懂如何用逆波兰符号法表示和栈...
来自: - 最后更新于:
逻辑表达式有如下形式: (1)原子式,用)组合式;若A 和B 是逻辑表达式,则非A”。 以上表达式的形式是固定的辑表达式,如果变换其中原子式的取值(真或假),该表达式的辑表达式(整个表达式最多10 个原子式,且辑表达式是可满足的,或者’n’表示转换成后缀表达式(二叉树),然后高手埃。。。。。 逆波兰式就是后缀表达式,我试过 ((a&~a)->z)这个表达式是什么啊 a...
来自: - 最后更新于:
学表达式转换成后缀式(逆波兰式),并对后缀式。 // 中缀表达式转化为后缀表达式,仅支持非负整数的表达式。 char* infix2postfix(const char *infix...
来自: - 最后更新于:
c))+d 的逆波兰式,三元式,四元式 写出:a*-(b+c) 的树形表download.gimoo.net/source/1345334/ 逆波兰式 /question74&index=1 三元式 /view/fd5c84c5bb4cf7ec4afed075.html 四元式 好东东 来...
来自: - 最后更新于:
知数的算术表达式(小米所在 的非常多,而且式子很长,老师则: 1.a+b 代表 a+2*b; 2.a-b 代表 a-3*b; 3.全表达式,对于每个式子输出一个数,表示该表达式的解。 输入格式: 输你一个算术表达式,式子中只含有度不超过10000,式子中的数均用栈进行存表达式,使用ascll码转过 查查括号表达式的逆波兰式,里面栈是...
来自: - 最后更新于:
本词条对我有帮助0
积木知识库中的词条内容仅供参考,如果您需要解决实际问题,建议您咨询相关领域专业人士
如果您认为本词条还需进一步完善,欢迎您也来参与编辑词条&&&&让我们共同来完善IT领域的百科全书
浏览该词条的网友还浏览了
最新收录词条
热门脚本语言:数据结构实验报告三-逆波兰表达式_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
喜欢此文档的还喜欢
数据结构实验报告三-逆波兰表达式
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢四则运算表达式求值
问题描述:四则运算表达式求值,将四则运算表达式用中缀表达式,然后用后序遍历的方式输出,并计算结果。
需求分析:
1,本程序需要输入一个中序表达式,并且打印相应的后序表达式及运算结果。
2,中序表达式由键盘输入。要进行输入的合法性判断,以回车结束输入。
3,在DOS界面输出后序表达式及运算结果
概要设计:
抽象数据类型:
为实现上述功能,可以采用二叉树来进行运算。首先将用户输入的中缀表达式作为字符串输入到字符数组内,让后在储存到二叉树内,最后用后序遍历输出。
数据对象:数值,操作符
&&&&&&&&&&
基本操作:写于后面
算法的基本思想:
每一个叶子结点有一个确定的值,对于每一个运算符结点,也可以看做它代表一个值,其值为左子树的值与右子树的值按照结点中存储的运算符计算后的结果。如结点’+’的值为“1+右子树的值”,而右子树的值为它的左子树的值乘以它的右子树的值,即”2*3”,所以表达式的值就是根节点的值”1+2*3”。
由上述递归的定义不难看出,建立表达式树就是建立树中的每一个结点,将每一个结点链接起来就是整棵树。而在建立深度低的结点时要将其左右指针指向之前建立的深度比它高一级的结点(如’*’要指向’2’和’3’,而’+’又要指向’*’)。这样我们可以用栈来存放每次建立的结点,按照优先级(表达式为中缀型)建立每一个结点。建立结点的顺序即为表达式求值的顺序。如果扫描到操作数则直接新建一个左右指针为空的结点,并压入结点栈中(存放结点指针)。遇到运算符时首先新建一个结点,然后从栈中依次弹出两个结点,并让新建立的结点的左右指针域指向它们。当所有结点建立完毕时,如果表达式没有错误(这里假设输入表达式正确),这时栈中应该只剩下一个结点,它就是所建立的表达式的根结点.&
建树的具体步骤:
建树过程中需要两个栈,stack
PTR;存放结点指针不用说,还需要一个存放运算符的栈stack
OPTR;。因为优先级与括号的作用,需要将因优先级低而暂时不能参与运算的运算符压入栈中。当读入的运算符与栈顶的运算符优先级相等或比起低时,这时建立栈顶运算符的结点并弹栈。直到栈顶运算符优先级低于读入运算符时,再将它压入栈中。若表达式扫描完毕stack
&char& OPTR中还有运算符,只需要依次弹出建立结点即可。
详细设计:
物理数据结构:采用二叉链表和顺序栈储存操作数及操作符
&&&&&&&&&&&&&
输入输出格式:输入:21+23*(12-6)
&&&&&&&&&&&&&&&&&&&&&&&&&&
输出:21_23_12_6_-*+(‘_’代表空格)
实验结果:
实验心得:首先要注意定义的数据结构是什么,
typedef char * TElemT
typedef struct BiTNode {
TElemType *
//data字符串中字符的个数
struct BiTNode * lchild, *
}BiTNode, *BiT
这里面的data是指针
其次是注意后序遍历的最初情况,
If(T)而不是IF(!T)
&程序如下:
#include &stdio.h&
#include &string.h&
#include &malloc.h&
#include &stdlib.h&
#include &stack&
#include &string.h&
#define STACK_INIT_SIZE 100
#define DATA_SIZE 10
#define STACKINCREMENT 10
#define OK&1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW -2
typedef float SE
typedef int S
typedef char * TElemT
typedef struct BiTNode {
& //data字符串中字符的个数
&struct BiTNode * lchild, *
}BiTNode, *BiT
typedef struct
&SElemtype *
&SElemtype *
Status IsDigital(char ch)
if(ch&='0'&&ch&='9')
&return 1; //是数字字母
&&& return 0;
//不是数字字母
int CrtNode(stack &BiTree&
&PTR, char *c)
&BiTNode * T;
&T = (BiTNode *)malloc(sizeof(BiTNode));
&T-&data = (char
*)malloc(DATA_SIZE*sizeof(char));
&while(IsDigital(c[i]))
&&T-&data [i] =
&T-&lchild =
T-&rchild = NULL;
&PTR.push (T);
void CrtSubTree(stack &BiTree&
&PTR, char c)
&BiTNode * T;
&T = (BiTNode *)malloc(sizeof(BiTNode));
&T-&data = (char
*)malloc(DATA_SIZE*sizeof(char));
&T-&data [0] =
&T-&len = 1;
&T-&rchild = PTR.top();
//先右子树,否则运算次序反了
&PTR.pop ();
&T-&lchild = PTR.top();
&PTR.pop ();
&PTR.push (T);
char symbol[5][5]={{'&', '&',
'&'},&&&&&&&
//符号优先级
&&&&&&&&&&&&&&&&&&&&
{'&', '&', '&',
'&', '&'},
&&&&&&&&&&&&&&&&&&&&
{'&', '&', '&',
'&', '&'},
&&&&&&&&&&&&&&&&&&&&
{'&', '&', '&',
'&', '&'},
&&&&&{'&',
'&', '&', '&',
&&&&&&&&&&&&&&&&&&
int sym2num(char
s)&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//返回符号对应优先级矩阵位置
return 4;&&
char Precede(char a, char
b)&&&&&&&&&&&&&&&&&&&
//返回符号优先级
return(symbol[sym2num(a)][sym2num(b)]);
void CrtExptree(BiTree &T, char exp[])
{//根据字符串exp的内容构建表达式树T
&stack &BiTree&
PTR;//存放表达式树中的节点指针
&stack &char&
OPTR;//存放操作符
&OPTR.push ('#');
&op = OPTR.top();
&while( !((exp[i]=='#')
&& (OPTR.top()=='#')) ) //与
&&if (IsDigital(exp[i]))
&&{//建立叶子节点并入栈 PTR
&&&i+=CrtNode(PTR,
&&else if (exp[i] == ' ')
&&&&&OPTR.push
= OPTR.top (); OPTR.pop ();
&&&&&while(op!='('){
&&&&&&CrtSubTree(PTR,
= OPTR.top (); OPTR.pop ();
&&&&&}//end
&&&&default:
//exp[i]是 + - * /
&&&&&while(!
OPTR.empty ())
= OPTR.top ();
(Precede(op, exp[i])=='&')
&&&&&&&CrtSubTree(PTR,
OPTR.pop ();
&&&&&if(exp[i]!='#')
&&&&&&OPTR.push
&&&&&&i++;
&&}//end else
&}//end while
&T = PTR.top();
&PTR.pop ();
void PostOrderTraverse(BiTree &T, char * exp
,int &count)
//后序遍历表达式树T,获取树中每个结点的数据值生成 逆波兰表达式 exp
//T是表达式树的根节点;字符串exp保存逆波兰表达式;count保存exp中字符的个数
//后序遍历中,处理根结点时,依据T-&len的值,把T-&data中的字符依次添加到当前exp字符串的尾端
//添加完T-&data后,再添加一个空格字符,同时更新count计数器的值。
PostOrderTraverse(T-&lchild,exp,count);
PostOrderTraverse(T-&rchild,exp,count);
strncpy(exp+count,T-&data,T-&len);
exp[count+=(T-&len)]=' ';
&& count++;
//---------------------------------
//逆波兰表达式计算
&Status InitStack(SqStack
&S.base = (SElemtype
*)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
&if (! S.base) exit(OVERFLOW);
&S.top = S.
&S.stacksize = STACK_INIT_SIZE;
&//printf("程序运行到构建栈\n");
&&& return
int StackLength(SqStack S)
&&& return
//printf("程序运行到获得堆栈元素的个数\n");
//获得堆栈元素的个数
Status Push(SqStack &S, SElemtype e)
if(S.top-S.base&=S.stacksize)
&&&&&&&&&&
S.base=(SElemtype
*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemtype));
&&&&&&&&&&
if(!S.base)
&&&&&&&&&&
exit(OVERFLOW);
&&&&&&&&&&
S.top=S.base+S.
&&&&&&&&&&
S.stacksize+=STACKINCREMENT;
*S.top++=e;
//printf("程序运行到入栈\n");
return OK;
Status Pop(SqStack &S, SElemtype
if(S.top==S.base)
return ERROR;
// printf("程序运行到出栈\n");
return OK;
&int EvalValue(char *ch, SqStack
& int i=0;
& SElemtype result=0;
& a=ch[i];
& while(IsDigital(a))
result=10*result+(int)(a-48);
a=ch[++i];
& Push(S, result);
& //printf("程序运行标志1\n");
void EvalExpr(char ch, SqStack &S)
float p ,q,r;
if((ch=='+')||(ch=='-')||(ch=='*')||(ch=='/'))
switch(ch)
&&&&&&&&&&&&&
case '+':r=p+q;
&&&&&&&&&&&&&
&&&&&&&&&&&&&
case '-':r=q-p;
&&&&&&&&&&&&&
&&&&&&&&&&&&&
case '*':r=q*p;
&&&&&&&&&&&&&
&&&&&&&&&&&&&
case '/':r=q/p;
&&&&&&&&&&&&&
&&&&&&&&&&&&&
&&&&&&&&&&
Push(S,r);
//printf("程序运行标志2\n");
//如果ch中保存的是操作符,则从堆栈中弹出两个元素,并把操作符应用在这两个元素之上,
//然后把操作结果压入到栈中。如果试图从栈中弹出两个元素是,该栈中并没有,那么该
//后缀表达式是不正确的。
Status evaluate (char ch[], float &
&SqStack S;
&Status St;
&&St = InitStack(S);
while(ch[i]!='#'&&i&100)
&& if(IsDigital(ch[i]))
i+=EvalValue(&ch[i], S);
&&else if(ch[i]==' ')
EvalExpr(ch[i], S);
&//如果到达表达式末尾时,栈中剩余元素不止一个,那么该
&//后缀表达式是不正确的。
& if(StackLength(S) ==1)
&&Pop(S, result);
&& //printf("表达式错误");
&&return ERROR;
&//printf("程序运行标志3\n");
&&return OK;
//-------------------------
&BiTree T;
&Status St;
&&char ch[100],c;
//输入的四则运算表达式
&char exp[100]; //逆波兰表达式
&int count=0;
&&printf("请输入表达式。回车表示结束\n");
&&while(i&100)
scanf("%c",&c);
&& ch[i++]=c;
&& if(c=='\n'){
ch[--i]='#';
&& }//end if
&CrtExptree(T, ch);//根据字符串ch的内容构建表达式树T
&//后序遍历表达式树T得到表达式的 逆波兰表达式
exp;count中保存exp中字符的个数
&PostOrderTraverse(T, exp, count);
&printf("逆波兰表达式为\n");
&for(i=0; i& i++)
&&printf("%c",exp[i]);
&printf("\n");
&exp[count] = '#'; //添加结束符
&St = evaluate (exp, result); //计算 逆波兰表达式 exp
&//输出计算的结果
&&printf("result
is& %5.2f \n", result);
&& printf("\n表达式错误\n");
& return 0;
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。湖南大学数据结构四则运算表达式报告 二叉树_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
湖南大学数据结构四则运算表达式报告 二叉树
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢问题补充&&
猜你感兴趣
服务声明: 信息来源于互联网,不保证内容的可靠性、真实性及准确性,仅供参考,版权归原作者所有!Copyright &
Powered by

我要回帖

更多关于 四则混合运算练习题 的文章

 

随机推荐