四则运算表达式求值实验报告
四则运算实验报告
实验3四则运算表达式求值背景在工资管理软件中,不可避免的要用到公式的定义及求值等问题。
对于数学表达式的计算,虽然可以直接对表达式进行扫描并按照优先级逐步计算,但也可以将中缀表达式转换为逆波兰表达式,这样更容易处理。
问题描述四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。
基本要求使用二叉树来实现。
实现提示利用二叉树后序遍历来实现表达式的转换,同时可以使用实验2的结果来求解后缀表达式的值。
输入输出格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。
输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
选作内容(1)在输入输出方式上要求使用:输入:将中缀表达式存于文本文件中,程序从该文本文件中读出表达式。
输出:如果该中缀表达式正确,则将后缀表达式输出到该文件中原表达式的后面,它们之间用“---”后相连;如果不正确,请在输出表达式错误提示到该文件原表达式的后面,它们之间用“---”相连。
(2) 利用堆栈来实现中缀表达式转换为后缀表达式。
测试用例输入:21+23*(12-6)输出:21 23 12 6 -*+程序代码:#include <iostream>#include <string.h>using namespace std;#define SIZE 100#define STACKINCREMENT 10template<class T>//栈class stack{public:void InitStack() {S.base = (T *)malloc(SIZE * sizeof(T));if(!S.base) exit(0);S.top = S.base;S.stacksize = SIZE;}void DestroyStack(){free(S.base);}void ClearStack(){S.top = S.base;}bool StackEmpty(){if(S.top == S.base) return true;else return false;}int StackLength(){return (S.top - S.base);}bool GetTop(T &t){if(S.top != S.base){t = *(S.top - 1);return true;}else return false;}void Push(T t){if(S.top - S.base >= S.stacksize){S.base = (T *)realloc(S.base,(S.stacksize + STACKINCREMENT) * sizeof(T));if(!S.base) exit(0);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top = t;S.top++ ;}bool Pop(T &t){if(S.top == S.base) return false;else S.top-- ;t = *S.top ;return true;}private:struct SqStack{T *base;T *top;int stacksize;}S;};class BiTree{private:struct BiTreeNode{char OPT[10];BiTreeNode *lchild,*rchild;};BiTreeNode *T; //T是根结点int index; //index是后缀表达式转换二叉树时的索引int number_of_point ;//销毁一颗树void DestroyTree(BiTreeNode *T){if(T){DestroyTree(T->lchild);DestroyTree(T->rchild);free(T);}}void DestroyTree(){DestroyTree(T);}//1表示栈顶优先级高于待入栈的元素int compare(char a,char b){ //定义了任意两个运算符的优先级if(a == '(' && b == ')') return 0;else if((a == '+' && b == '*') || (a == '+' && b == '/') || (a == '-' && b == '*') || (a == '-' && b == '/')|| (a != ')' && b == '(') || (a == '(' && b != ')'))return -1;else return 1;}//递归构造start,end分别是一个式子开始值和结束值的索引/*递归构造中缀表达式转化为的二叉树(利用栈) */void InorderCreate(BiTreeNode *&T,char str[30][10],int start,int end){ if(start == end) { //递归终止if(!(T = (BiTreeNode *)malloc(sizeof(BiTreeNode)))) exit(0);strcpy(T->OPT,str[start]);T->lchild = NULL;T->rchild = NULL;}else{stack<char> opt;stack<int> num;num.InitStack();opt.InitStack();char last;int index;int a;bool jump = false;for(int i = start;i <= end;i++) { //begin求解优先级最小的一个运算符if(jump) break;number_of_point = 0 ;if(IsNumber(str[i][0]) || str[i][0] == '-' &&IsNumber(str[i][1]) )continue;else{char c = str[i][0];char b;if(i == start && c == '(') {start += 1;continue;}else if(opt.StackEmpty() || (opt.GetTop(b) && compare(b,c) == -1)){opt.Push(c);num.Push(i);}else{if(c != ')'){opt.Pop(b);num.Pop(a);if(!opt.StackEmpty()){opt.GetTop(b);if(compare(b,c) == 1){opt.Pop(b);num.Pop(a);opt.Push(c);num.Push(i);}else{opt.Push(c);num.Push(i);}}else{opt.Push(c);num.Push(i);}}else{for(opt.GetTop(b);compare(b,c) != 0;opt.GetTop(b)){opt.Pop(b);num.Pop(a);if(opt.StackEmpty()){opt.Push(b);num.Push(a);end -= 1;jump =true;break;}}if(compare(b,c) == 0) {opt.Pop(b);num.Pop(a);}}}}} //end,得到的是该步中的根结点字符last及其索引indexopt.Pop(last);num.Pop(index);if(!opt.StackEmpty()){opt.Pop(last);num.Pop(index);}opt.DestroyStack();num.DestroyStack();if(!(T = (BiTreeNode *)malloc(sizeof(BiTreeNode)))) exit(0);T->OPT[0] = last;T->OPT[1] = '\0';InorderCreate(T->rchild,str,start,index-1);InorderCreate(T->lchild,str,index+1,end);}}bool IsNumber(char a){ //判断一个字符是否为数值形式的if( a == '.' && number_of_point == 0 ) {number_of_point ++ ;return true;}else if('0' <= a && a <= '9') return true ;else return false;}//递归求解树表示的表达式的值double Operate(BiTreeNode *T){if(T->lchild==NULL && T->rchild==NULL){double num = atof(T->OPT); //调用系统函数atof()将字符串转换为浮点数return num;}double ld,rd;ld = Operate(T->lchild);rd = Operate(T->rchild);char c = T->OPT[0];switch(c){case '+': return ld+rd;break;case '-': return rd-ld;break;case '*': return ld*rd;break;case '/': return rd/ld;break;default:cout << " you have entered wrong data ! "<< endl ;return 0;break ;}}void display(BiTreeNode *T){if(T == NULL ) return ;display(T->rchild);display(T->lchild);cout << T->OPT << " " ;public:BiTree() {T = NULL ;index = 0 ;number_of_point = 0 ;}/*以下两个函数重载私有成员函数方便计算*/void InorderCreate(){char OPT[30][10];cout << "输入中缀表达式: " << endl;char c = getchar();bool flag = true;int i = 0,j = 0 ;while(c != 10) { //输入的是空格j = 0;if(c == '-' && flag == true) { //flag判断是否是一个负数的值OPT[i][j++] = c;for(c = getchar() ; IsNumber(c) ; c = getchar() )OPT[i][j++] = c;OPT[i++][j] = '\0';flag = false;}else if(IsNumber(c)){OPT[i][j++] = c;for(c = getchar();IsNumber(c);c = getchar())OPT[i][j++] = c;OPT[i++][j] = '\0';flag = false;}else //运算符时的处理{flag = true;OPT[i][j++] = c;OPT[i++][j] = '\0';c = getchar();}}InorderCreate(T,OPT,0,i-1);}double Operate(){return Operate(T);}void display(){display(T) ;}~BiTree() {DestroyTree();};int main(){BiTree tree;tree.InorderCreate();cout << endl << tree.Operate() << endl;tree.display() ;cout << endl ;return 0;}测试结果:。
【7A版】四则运算表达式求值实验报告
HUNANUNIVERSITY课程实习报告题目:四则运算表达式求值学生姓名:学生学号:专业班级:指导老师:完成日期:一、需求分析四则运算表达式求值,将四则运算表达式用中缀表达式表示,然后转换为后缀表达式,并计算结果。
本程序要求利用二叉树后序遍历来实现表达式的转换,同时可以使用实验2的结果来求解后缀表达式的值。
在字符界面上输入一个中缀表达式,回车表示结束。
如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
测试数据输入:21+23G(12-6)输出:2123126-G+二、详细设计输入和输出的格式输入本程序可以将输入的四则运算表达式(中缀表达式)转换为后缀表达式输出后缀表达式为://输出结果的位置表达式的值为://输出结果的位置三、调试分析本次实验的难点主要是在建立二叉树的问题上。
关于如何把中缀表达式存入二叉树中,我参考了网上的一些方法,成功实现了目标,但是却遇到了一个问题,那就是不能处理小数,甚至两位或两位以上的整数。
因为如果采用字符数组来存储操作数,运算符合一位整数还可以处理,但对于两位数就就会出问题,最后我改进采用字符串数组来存储操作数,成功解决了问题。
另外在处理输入的非法表达式问题中,我也费了很大功夫,但总体问题不大。
四、测试结果五、用户使用说明(可选)1、运行程序时提示输入四则运算表达式本程序可以将中缀表达式转化为后缀表达式,并计算结果请输入四则运算表达式:输出后缀表达式为:表达式的值为:程序源代码(c++)#include<iostream>#include<string>#include<stack>#include<iomanip>constintMaG=100;usingnamespacestd;classNode{public:charch[MaG];//考虑到数值有时会是两位数,所以使用字符串数组NodeGlChild;NodeGrChild;Node(){strcpy(ch,"");lChild=rChild=NULL;}~Node(){if(lChild!=NULL)deletelChild;if(rChild!=NULL)deleterChild;}};staticintcount=0;staticchararray[MaG];//保存原始的中缀表达式staticcharstr[2GMaG];//保存后序遍历出来的字符串,为表达式求值提供方便staticintk=0;chargetOp(NodeGtemp);//temp指针保存每个结点,返回的是运算符NodeGcrtTree(NodeGroot);//传入根结点指针,返回根结点指针voidoutput(NodeGroot);//获得处理后的字符串boolisError(char);//判断字符是否有问题voiddeal();//对字符数组进行处理doublevalue(string);//计算后缀表达式,得到其结果。
表达式求值实验报告
表达式求值的类型定义与操作实现一、需求分析设计一个程序,演示用算符优先法对算术表达式求值的过程。
利用算符优先关系,实现对算术四则混合运算表达式的求值。
(1)输入的形式:表达式,例如2*(3+4)#;包含的运算符只能有'+' 、'-' 、'*' 、'/' 、'('、')';(2)输出的形式:运算结果,例如Answer is:77.000000;(3)程序所能达到的功能:对表达式求值并输出结果。
二、概要设计:本课程设计需要用到抽象数据类型栈存储表达式。
本部分给出栈的类型定义与表达式求值操作描述。
1、存储结构(顺序栈):typedef struct SqStack{SElemType *base;SElemType *top;int stacksize;}SqStack;2、基本操作:Status InitStack(SqStack &s)操作结果:初始化一个空栈s。
Status GetTop(SqStack s,SElemType &e)初始条件:栈s已存在。
操作结果:得到s的栈顶元素并用e带回。
Status Push(SqStack &s,SElemType e)初始条件:栈s已存在。
操作结果:向栈s中压入元素e。
Status Pop(SqStack &s,SElemType &e)初始条件:栈s已存在‘操作结果:弹出栈s栈顶元素,并用e带回。
Status In(char e)操作结果:判断e是否为7种运算符之一char Precede(char p,char c)操作结果:比较运算符p与运算符c的优先级。
SElemType Operate(SElemType x,char n,SElemType y)操作结果:计算x,y对运算符n的运算结果。
三、详细设计本部分主要给出表达式求值的实现算法1、初始化一个空栈sStatus InitStack(SqStack &s) //{s.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!s.base)exit(OVERFLOW);s.top=s.base;s.stacksize=STACK_INIT_SIZE;return OK;}2、读取栈顶元素Status GetTop(SqStack s,SElemType &e){if(s.top==s.base)return ERROR;e=*(s.top-1);return OK;}3、向栈s中压入元素eStatus 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.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;return OK;}4、弹出栈顶元素Status Pop(SqStack &s,SElemType &e) //{if(s.top==s.base)exit(OVERFLOW);e=* --s.top;return OK;}5、判断是否为7种运算符之一Status In(char e) / /{switch(e){case '+':case '-':case '*':case '/':case '(':case ')':case '#':return(1);break;default:return(0);}}6、比较两运算符优先级char Precede(char p,char c){ 'switch(p){case '+':case '-':switch(c){case '*':case '/':case '(':return '<';break;default:return '>';break;}break;case '*':case '/':switch(c){case '(':return '<';break;default:return '>';break;}break;case '(':switch(c){case ')':return '=';break;case '#':printf("ERROR!!\n");exit(OK);default:return '<';break;}break;case ')':switch(c){case '(':printf("ERROR!!\n");exit(OK);default:return '>';break;}break;case '#':switch(c){case ')':printf("ERROR!!\n");exit(OK);case '#':return '=';break;default:return '<';break;}break;}}7、四则运算SElemType Operate(SElemType x,char n,SElemType y) {SElemType e;switch(n){case '+':e=x+y;break;case '-':e=x-y;break;case '*':e=x*y;break;case '/':if(y==0){printf("分母不能为0!\n");exit(1);}else{e=x/y;break;}}return e;}8、主函数进行表达式求值void main(){SqStack OPTR,OPND;SElemType p,s,a,b,theta;char c;printf("请输入一个表达式并以'#'结束\n(只包括' +-*/' 和'('')'):\n");InitStack(OPTR);Push(OPTR,'#');InitStack(OPND);c=getchar();GetTop(OPTR,p);while(c!='#'||p!='#'){if(!In(c)){s=c-48;c=getchar();while(c>='0'&&c<='9'){s=s*10+(c-48);c=getchar();}Push(OPND,s);}else{switch(Precede(p,c)){case '<':Push(OPTR,c);c=getchar();break;case '=':Pop(OPTR,s);c=getchar();break;case '>':Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,theta,b));break;}GetTop(OPTR,p);}}//whileprintf("\n\n");GetTop(OPND,p);printf("Answer is:%f\n",p);getch();}四、调试分析1、初始化了一种类型的两个栈,分别用来存放数值和运算符。
c语言四则运算实验报告
深圳大学实验报告课程名称: ________ C 语言实验 ________________实验名称: 100以内的四则运算游戏 _________学 院: ___________ 信息工程学院 ______________指导教师 ______________ 张金凤 __________________报告人: 王文杰 组号:]7 ________学号 2013130073 实验地点 教学楼D506实验时间: 2014 年 4 月 16 日提交时间: ___________ 2014.5.9 ____________________课程编号 1300050027一、实验目的一、学习和掌握c语言函数的泄义与调用:二、进一步掌握随机数、选择结构、循环控制、交互式输入输出等程序设计方法:三、进一步掌握c语言中的数组左义和引用方法:四、学习和掌握根据流程图进行模块化程序设计的思想*二、实验要求产生1到4之间的随机数,决定4则运算的符号,再产生两个0到99的随机数进行运算,并记录下做的题数以及正确的数目,当做题者输入n或N时退出程序并显示出完成题数及正确率。
int num2); int五、对流程图的简要说明:#include <std io. h> #include <stdlib. h> #include Htime. h" #include <conio. h> void max_min(int a, int b); randN1N2(int rN1f int rN2 ); rand0per4(); randL/ntlOO ();addLmt100(int num1vsubLmt100(int num1fmulLmt100(int num1fdivLmt100(int num1f/*主函数的功能如下:在主函数中调用上面定义的五个函数,在屏幕上随机循环出一道 100以内的四则运算题。
小学四则运算实验报告
石家庄经济学院“高级语言程序设计”课程实习报告班级:试点2班姓名:贺迎春学号:410109030221日期:2011-10-19目录1.实习目的 (3)2.实习题目与程序功能 (3)3.算法设计 (3)4. 主要数据结构和标识符及其说明 (4)5. 程序运行实例 (5)6. 源程序清单 (6)7. 实习体会 (9)1.实习目的(1)掌握分支语句、循环语句的基本语法、语义。
(2)熟练使用if语句、case语句进行分支结构的程序设计、熟练使用for语句、repeat语句、while语句进行循环结构的程序设计。
(3)掌握嵌套的分支、循环结构。
(4)掌握基本的程序调试技能。
能够使用Trace Into、step over步进追踪,断点等控制程序的运行步骤,能够使用Watch监视表达式的值,并且点击project点击options点击compiler点击optimization把代码优化去掉,这样件事变量的之就能显示出来、添加条件断点等等。
(5)能够合理的设计程序的测试用例并验证程序的有效性能。
2.实习题目与程序功能实习题目:小学生的加减乘除以及混合运算的自动出题及评分系统。
功能描述:系统首先会给出提示信息,根据提示信息,当n=1时,系统会自动出10道十以内的加法练习题目并自动评分;当n=2时,系统会自动出10道十以内的减法练习题目并自动评分;当n=3时,系统会自动出10道十以内的乘法练习题目并自动评分;当n=4时,系统会自动出10道十以内的除法练习题目并自动评分;当n=5时,系统会自动出10道十以内的混合运算题目并自动评分;当n=6时,结束练习,退出系统;性能要求:要保证程序有足够的健壮性。
3.算法设计(1)分析①此系统的使用对象使小学生,所以加法、减法、乘法以及除法都是10以内的整数,并没有涉及到小数的问题。
小学生并未学习负数,所以当减法自动出题时,把答案为负数的情况删掉;而除法,则是利用10以内的整数相乘采用逆思维的方法来生成的。
C语言实验报告四则运算
《C语言》课内实验报告学生姓名:及学号:学院:班级:课程名称:C语言实验题目:实验二选择结构程序设计指导教师姓名及职称:年月日一、实验目的1.掌握逻辑表达式和if语句、嵌套的if语句、switch语句和break语句的格式、语义。
2.掌握选择结构程序设计方法。
二、实验内容编写程序实现两个数的四则运算,要求从键盘输入进行运算的两个数字以及相应的运算符('+'、'-'、'*'、'/'),程序给出算数表达式及运算结果。
(如下图所示,要求使用if语句和switch语句两种方法实现)三、实验结果1、流程图2、源程序(1)使用if语句#include <stdio.h>void main(){float a,b;char c;printf("please input two numbers:");scanf("%f%f",&a,&b);getchar();printf("\nplease input the operator:");//fflush(stdin);scanf("%c",&c);printf("\n");if(c=='+')printf("%10.2f+%10.2f=%10.2f\n",a,b,a+b);else if (c=='-')printf("%10.2f-%10.2f=%10.2f\n",a,b,a-b);else if (c=='*')printf("%10.2f*%10.2f=%10.2f\n",a,b,a*b);else if (c=='/')printf("%10.2f/%10.2f=%10.2f\n",a,b,a/b);elseprintf("Input error!\n");}(2)使用switch语句#include <stdio.h>void main(){float a,b;char c;printf("please input two numbers:");scanf("%f%f",&a,&b); //输入a,b的值getchar();printf("\nplease input the operator:"); //输入操作符scanf("%c",&c);printf("\n");switch(c) //判断输入操作符{case '+': //若操作符为'+',输出a+b printf("%10.2f+%10.2f=%10.2f\n",a,b,a+b);break;case '-': //若操作符为'-',输出a-b printf("%10.2f-%10.2f=%10.2f\n",a,b,a-b);break;case '*': //若操作符为'*',输出a*b printf("%10.2f*%10.2f=%10.2f\n",a,b,a*b);break;case '/': //若操作符为'/',输出a/b printf("%10.2f/%10.2f=%10.2f\n",a,b,a/b);break;default:printf("Input error!\n");}}2、运行结果输入12、13以及+,得到结果如下:输入12、13以及-,得到结果如下:输入12、13以及*,得到结果如下:输入12、13以及/,得到结果如下:输入12、13以及a,得到结果如下:3、结果分析题目要求编程实现两个数的四则运算,因此只需判断输入的操作符为四则运算中的哪一个,编程时可以使用if语句或者switch语句实现判断过程。
数据结构表达式求值(中缀)实验报告
数据结构表达式求值(中缀)实验报告题目名称表达式求值学号姓名指导教师日期一1. 问题描述:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。
2. 表达式求值这个程序,主要利用栈和数组,把运算的先后步骤进行分析并实现简单的运算,以字符列的形式从终端输入语法的正确的、不含变量的整数表达式。
利用已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。
该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。
1、基本思想(中缀表达式求值)要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式,要了解算术四则运算的规则即:(1)先乘除后加减;(2)从左到右计算;(3)先括号内,后括号外。
下表定义的运算符之间的关系:b + - * / () # a+ > > < < < > > _ > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # < < < < < =为了实现运算符有限算法,在程序中使用了两个工作栈。
分别是:运算符栈OPTR,操作数栈OPND.基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈得栈顶运算符比较优先级后作相应操作。
数据结构课程设计四则运算表达式求值(C语言版)
数据结构课程设计四则运算表达式求值(C语⾔版) 明⼈不说暗话,直接上,输⼊提取码z3fy即可下载。
⽂件中包含程序,程序运⾏⽂件,设计报告和测试样例,应有尽有,欢迎⼩伙伴们在中下载使⽤。
本课程设计为四则运算表达式求值,⽤于带⼩括号的⼀定范围内正负数的四则运算标准(中缀)表达式的求值。
注意事项:1、请保证输⼊的四则表达式的合法性。
输⼊的中缀表达式中只能含有英⽂符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及⼩数点“.”,输⼊“=”表⽰输⼊结束。
例如9+(3-1)*3.567+10/2=,特别是请勿输⼊多余空格和中⽂左右括号。
2、输⼊的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。
3、请保证输⼊的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。
本课程设计中操作数是C语⾔中的双精度浮点数类型。
4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。
下⾯的程序正常运⾏需要在上⾯的百度⽹盘中下载相应⽂件,否则⽆法正常使⽤哦。
1/*本程序为四则运算表达式求值系统,⽤于计算带⼩括号的四则运算表达式求值。
2具体算法:3先将字符串处理成操作单元(操作数或操作符),再利⽤栈根据四则运算4的运算法则进⾏计算,最后得出结果。
*/56 #include<stdio.h>7 #include<ctype.h>8 #include<stdlib.h>9 #include<string.h>10 #include<stdlib.h>11 #include<ctype.h>1213const int Expmax_length = 1001;//表达式最⼤长度,可根据适当情况调整14struct Ope_unit15 {//定义操作单元16int flag;//=1表⽰是操作数 =0表⽰是操作符 -1表⽰符号单元17char oper;//操作符18double real;//操作数,为双精度浮点数19 };2021void Display();//菜单22void Instru(); //使⽤说明23int Check(char Exp_arry[]);24void Evalua(); //先调⽤Conver操作单元化,再调⽤Calculate函数计算结果并输出25int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元26int Isoper(char ch);//判断合法字符(+ - * / ( ) =)27int Ope_Compar(char ope1,char ope2);//操作符运算优先级⽐较28double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//⽤栈计算表达式结果29double Four_arithm(double x,double y,char oper);//四则运算3031int main()32 {33int select;34while(1)35 {36 Display();37 printf("请输⼊欲执⾏功能对应的数字:");38 scanf("%d",&select);39 printf("\n");40switch(select)41 {42case1: Evalua(); break;43case2: Instru(); break;44case0: return0;45default : printf("⽆该数字对应的功能,请重新输⼊\n");46 system("pause");47 }48 }49return0;50 }5152int Check(char Exp_arry[])53 {//检查是否有⾮法字符,返回1表⽰不合法,0表⽰合法54int Explength=strlen(Exp_arry),i;55for(i=0;i<Explength;i++)56 {57if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))58return1;59if(isdigit(Exp_arry[i]))60 {61int Dig_number=0,Cur_positoin=i+1;62while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')63 {64 Dig_number++;65 Cur_positoin++;66 }67if(Dig_number >= 16)//最多能够计算15位有效数字68return1;69 }70 }71return0;72 }7374void Evalua()75 {//先调⽤Conver函数将字符串操作单元化,再调⽤Calculate函数计算结果并输出76char Exp_arry[Expmax_length];77int flag=0;//假设刚开始不合法,1表达式合法,0不合法78struct Ope_unit Opeunit_arry[Expmax_length];7980 getchar();//吃掉⼀个换⾏符81 printf("请输⼊四则运算表达式,以=结尾:\n");82 gets(Exp_arry);83 flag=Check(Exp_arry);84if(flag)85 printf("该表达式不合法!\n");86else87 {88int Opeunit_count = Conver(Opeunit_arry,Exp_arry);89double ans = Calculate(Opeunit_arry,Opeunit_count,flag);90if(flag)91 {92 printf("计算结果为:\n");93 printf("%s%lf\n",Exp_arry,ans);94 }95else96 printf("该表达式不合法!\n");97 }98 system("pause");99 }100101int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])102 {//将字符串操作单元化103int Explength=strlen(Exp_arry);104int i,Opeunit_count=0;105for(i=0;i<Explength;i++)106 {107if(Isoper(Exp_arry[i]))//是操作符108 {109 Opeunit_arry[Opeunit_count].flag=0;110 Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];111 }112else//是操作数113 {114 Opeunit_arry[Opeunit_count].flag=1;115char temp[Expmax_length];116int k=0;117for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++)118 {119 temp[k++]=Exp_arry[i];120 }121 i--;122 temp[k]='\0';123 Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数124125//负数126if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0127 && Opeunit_arry[Opeunit_count-1].oper=='-')128 {129 Opeunit_arry[Opeunit_count-1].flag = -1;130 Opeunit_arry[Opeunit_count].real *= -1;131 }// -9132if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0133 && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 134 && Opeunit_arry[Opeunit_count-2].oper !=')')135 {136 Opeunit_arry[Opeunit_count-1].flag = -1;137 Opeunit_arry[Opeunit_count].real *= -1;138 }// )-9139140//正数141if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0142 && Opeunit_arry[Opeunit_count-1].oper=='+')143 {144 Opeunit_arry[Opeunit_count-1].flag = -1;145 }// +9146if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0147 && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0148 && Opeunit_arry[Opeunit_count-2].oper !=')')149 {150 Opeunit_arry[Opeunit_count-1].flag = -1;151 }// )+9152 Opeunit_count++;153 }154 }155/*for(i=0;i<Opeunit_count;i++)156 {//查看各操作单元是否正确,1是操作数,0是操作符157 if(Opeunit_arry[i].flag == 1)158 printf("该单元是操作数为:%lf\n",Opeunit_arry[i].real);159 else if(Opeunit_arry[i].flag == 0)160 printf("该单元是操作符为:%c\n",Opeunit_arry[i].oper);161 else162 printf("该单元是负号符为:%c\n",Opeunit_arry[i].oper);163 }*/164return Opeunit_count;165 }166167double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)168 {//根据运算规则,利⽤栈进⾏计算169int i,dS_pointer=0,oS_pointer=0;//dS_pointer为操作数栈顶指⽰器,oS_pointer为操作符栈顶指⽰器170double Dig_stack[Expmax_length];//操作数栈(顺序存储结构)171char Ope_stack[Expmax_length];//操作符栈172173for(i=0;i<Opeunit_count-1;i++)174 {175if( Opeunit_arry[i].flag != -1 )176 {177if(Opeunit_arry[i].flag)//是操作数178 {179 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//⼊操作数栈180//printf("%lf\n",Digit[dS_pointer-1]);181 }182else//是操作符 + - * / ( )183 {184//操作符栈为空或者左括号⼊栈185if(oS_pointer==0 || Opeunit_arry[i].oper=='(')186 {187 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;188//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);189 }190else191 {192if(Opeunit_arry[i].oper==')')//是右括号将运算符⼀直出栈,直到遇见左括号193 {194 oS_pointer--;//指向栈顶195 dS_pointer--;//指向栈顶196while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)197 {198 Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 199 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈200201 dS_pointer--;//前⼀个操作数出栈202//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);203 }204 oS_pointer--;//左括号出栈205206 oS_pointer++;//恢复指向栈顶之上207 dS_pointer++;208 }209else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和栈顶元素⽐较210 {211 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;212//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);213 }214else//运算符出栈,再将该操作符⼊栈215 {216 oS_pointer--;//指向栈顶217 dS_pointer--;//指向栈顶218while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1) 219 {//当前操作符⽐栈顶操作符优先级⾼220 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 221 Ope_stack[oS_pointer--]);222 dS_pointer--;223//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);224 }225 oS_pointer++;//恢复指向栈顶之上226 dS_pointer++;227 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;228 }229 }230 }231 }232 }233/*for(i=0;i<oS_pointer;i++)234 printf("操作符栈%oS_pointer\Ope_u_count",Operator[i]);235 for(i=0;i<dS_pointer;i++)236 printf("操作数栈%lf\n",Digit[i]);*/237 oS_pointer--;//指向栈顶元素238 dS_pointer--;//指向栈顶元素239while(oS_pointer != -1)240 {241 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 242 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈243 dS_pointer--;//前⼀个操作数出栈244//printf("操作数栈顶元素为%lf\Ope_u_count",Digit[dS_pointer]);245 }246//printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);247if(oS_pointer==-1 && dS_pointer==0)248 flag=1;//为1表⽰表达式合法249return Dig_stack[0];250 }251252int Ope_Compar(char ope1,char ope2)253 {//操作符运算优先级⽐较254char list[]={"(+-*/"};255int map[5][5]={//先⾏后列,⾏⽐列的运算级优先级低为0,⾼为1256// ( + - * /257/* ( */1,0,0,0,0,258/* + */1,0,0,0,0,259/* - */1,0,0,0,0,260/* * */1,1,1,0,0,261/* / */1,1,1,0,0 };262int i,j;263for(i=0;i<5;i++)264if(ope1==list[i]) break;265for(j=0;j<5;j++)266if(ope2==list[j]) break;267return map[i][j];268 }269270double Four_arithm(double x,double y,char oper)271 {//四则运算272switch(oper)//保证不含其它运算符273 {274case'+': return x+y;275case'-': return x-y;276case'*': return x*y;277case'/': return x/y;//y不能为0278default : return0;279 }280 }281282int Isoper(char ch)283 {//判断合法字符 + - * / ( ) =284if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=')285return1;286return0;287 }288289void Display()290 {//打印菜单291 system("cls");292 printf("/******************************************************************************/\n");293 printf("\t\t 欢迎使⽤本四则运算表达式求值系统\n");294 printf("\n\t说明:建议请您先阅读使⽤说明,再输⼊相应的数字进⾏操作,谢谢配合!\n"); 295 printf("\n\t\t1 四则运算表达式求值\n");296 printf("\n\t\t2 使⽤说明\n");297 printf("\n\t\t0 退出\n");298 printf("/******************************************************************************/\n");299 }300301void Instru()302 {//打印使⽤说明303 FILE *fp;304char ch;305if( ( fp=fopen("使⽤说明.txt","r") ) == NULL)306 {307 printf("⽂件打开失败!\n");308 exit(0);309 }310for(; (ch = fgetc(fp)) != EOF; )311 putchar(ch);312 fclose(fp);313 printf("\n");314 system("pause");315 }。
计算数学表达式程序设计实训报告
程序设计实训报告题目:计算数学表达式程序1、课程设计目的(1)复习巩固java语言的基础知识,进一步加深对java语言的理解和掌控(2)课程设计为大家提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机结合起来,锻炼我们的分析解决实际问题的能力。
提高我们适应实际,实践编程的能力。
(3)培养我们在项目开发中创新意识及能力,通过亲身实践,利用所学编写简单的面向对象程序,提高对面向对象及JAVA语言的理解。
2、设计题目分析2.1 题目要求:(1)由用户输入一个简单的四则运算表达式,求出其计算结果后显示。
(2)允许在表达式中出现常用的数学函数,如取整、三角函数、倒数、平方根、平方、立方等。
2.2 界面要求:(1)尽量使用图形界面实现,要符合日常软件使用规范来设计菜单和界面。
(2)如果无法实现图形界面,则在命令行方式下也需要提供菜单,方便用户操作。
2.3 设计要求及需求分析设计要求:由于现代用户更倾向于由鼠标方便操作的图形用户界面,所以我们采用GUI来实现计算器,并采用Swing组件,AWT事件处理等实现具体功能。
需求分析:在我们日常生活中,计算开支、收入时,大额数字或是多倍小数的计算都需要计算器的帮助,而在学习一些科目时,也常常要处理数字。
虽然现在的计算器价格比较低廉,但是功能过于简单的不能满足个人需求,功能多的价格较贵,不仅操作不便,很多功能也根本用不到。
所以我们想用自己所学设计开发一个属于自己的简单计算器来完成日常学习生活的需求。
3、课程设计内容3.1 总体设计:3.2 详细设计:以下是部分类功能的说明:CalFrame //构造新窗体CalPanelL //定义面板容器CalButton//定义按钮3.3 调试与测试:包括程序调试过程、数据测试结果分析,测试过程中遇到的主要问题及采取的解决措施;(列出主要问题的出错现象、出错原因、解决方法及效果等)。
主要问题:1.标点符号问题,经常出现漏打分号,忽略中英文标点转换等问题,所以一定要谨慎仔细.2.进制转换的实现及正/余弦计算经常出现问题,结果不正确,经过查阅资料及反复调试,我们终于克服了这一难题.3.界面设计,开始我们的设计不太合理,各类功能键排序不合理,看起来杂乱无章,既不美观也不实用。
数据结构》课程设计报告-实现对算术四则溷合运算表达式的求值以及大整数计算
江汉大学文理学院课程设计报告课程名称:设计题目:系别:专业:组别:学生姓名:起止日期:年月日~年月日指导教师:承诺书本人郑重声明:本人所呈交的学术论文,是本人在导师指导下独立进行研究工作所取得的成果。
除文中已经注明引用的内容外,本论文不包括任何其他个人或集体已经发表或撰写过的作品成果。
对本文的研究作出重要贡献的个人和集体,均已在文中以明确的方式标明。
本人完全意识到本声明的法律结果由本人承担。
学生(签名):年月日《数据结构》课程设计报告题目:实现对算术四则混合运算表达式的求值以及大整数计算一.设计目的数据结构是计算机专业的核心课程,是一门实践性很强的课程。
课程设计是加强学生实践能力的一个强有力手段,要求学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并上机调试的基本方法,还要求学生在完成程序设计的同时能够写出比较规范的设计报告。
严格实施课程设计这一环节,对于学生基本程序设计素养的培养和软件工作者工作作风的训练,将起到显著的促进作用。
二.问题描述(一)当用户输入一个合法的算术表达式后,能够返回正确的结果。
能够计算的运算符包括:加、减、乘、除、括号;能够计算的操作数要求在实数范围内;对于异常表达式能给出错误提示。
(二)求两个不超过200位的非负整数的和,积和商。
三.调试与操作说明(一)需求分析本程序所做的工作为:能直接求出四则表达式的值,并输出;可以解决因数值位数太大unsigned类型都无法表示的大数之间的运算。
本程序可用于小学教师对学生作业的快速批改以及对数值位数要求较大的科学运算。
此程序规定:1.程序的主要功能包括两部分:表达式求解和大整数的运算。
2.表达式求解中输入的必需为一个正确的四则表达式,可以是整型也可以为浮点型,比如:3*(7-2)+5和3.154*(12+18)-23。
大整数的运算中根据提示要输入两行数据位数不能大于200位。
3.程序的输出:表达式求解中为一浮点型数据,大整数运算中输出的即为运算之后的结果,结果里不能有多余的前导0。
程序设计实训报告—表达式求值问题
程序设计实训报告—表达式求值问题完成者:何炜班级:计科1501学号:完成日期:2016年7月14日星期四目录一、题目的内容及要求................................. 错误!未定义书签。
二、需求分析 ................................................ 错误!未定义书签。
三、概要设计 ................................................ 错误!未定义书签。
四、详细设计 ................................................ 错误!未定义书签。
五、源代码 .................................................... 错误!未定义书签。
六、运行结果及分析..................................... 错误!未定义书签。
七、收获及体会............................................. 错误!未定义书签。
一、题目的内容及要求求解形如(a+b)*((c+d)*e+f*h*g)的简单算术表达式的求值问题。
这种表达式只包括加、减、乘、除4种运算符。
为了实现表达式求值,可以首先读入原表达式(包括括号)并创建对应二叉树,其次对二叉树进行前序遍历、中序遍历、后续遍历(非递归),并输出逆波兰表达式,最后求解原表达式的值,同时对非法表达式格式能予以判断。
用二叉树的结构来存储表达式,后续遍历二叉树即可得到逆波兰表达式二、需求分析本程序能解决形如(a+b)*((c+d)*e+f*h*g)并以’#’作为结束标志的简单算术表达式的求值问题。
不仅能够求解出多位浮点数,而且能够对简单的非法表达式进行判断以避免程序异常退出。
三、概要设计1.用户输入中缀表达式2.程序将中缀表达式用二叉树的链式存储结构存储下来3.前序、中序遍历这颗二叉树,输出对应的前缀、中缀表达式4.后续遍历(非递归)这颗二叉树,并把遍历结果存储在顺序栈内,并输出后缀表达式5.对后缀表达式进行求值四、详细设计以下对概要设计进行详细的原理分析。
算术表达式求值演示实验报告
实验报告题目:算术表达式求值演示班级:网络工程2班姓名:陈智鸣学号:1225112005 完成日期:2013.10.24一、需求分析1. 问题描述:表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个经典例子。
设计一个程序演示用算符优先法对算术表达式求值的过程。
2. 基本要求:利用教科书表3.1给出的算符优先关系,实现对算术四则混合运算表达式的求值。
3. 测试数据:教科书例3-1的算术表达式3*(7-2)。
二、概要设计(算法描述)基本操作:InitStack_f(&S)操作结果:构造一个空栈S。
GetTop_f(&S,&e)初始条件:栈S已存在。
操作结果:用e返回S的栈顶元素。
Push_f(&S,ch)初始条件:栈S已存在。
操作结果:插入元素ch为新的栈顶元素。
Pop_f(&S,&e)初始条件:栈S已存在。
操作结果:删除S的栈顶元素,并以e返回其值。
}ADT SqStack_f三、详细设计代码如下:#include <iostream>#include <stack>using namespace std;int Operate(int x,char op,int y) //四则运算符的运算定义{switch(op){case'+': return x+y;case'-': return x-y;case'*': return x*y;case'/': return x/y;}}char Precede(char op1,char op2) //判断符号的优先级{if(((op1=='+'||op1=='-')&&(op2=='+'||op2=='-'||op2==')'||op2=='#'))||((op1=='*'||op1=='/')&&( op2=='+'||op2=='-'||op2=='*'||op2=='/'||op2==')'||op2=='#')))return '>';if((op1=='('&&op2==')')||(op1=='#'&&op2=='#'))return '=';elsereturn '<';}void Tonumber(char &c,stack<int>&OPND) //转化为数字{ int number=0;if(((c-'0')>=0&&(c-'0')<=9)){while(((c-'0')>=0&&(c-'0')<=9)){number=number*10+(c-'0');cin>>c;}OPND.push(number);}}int main(){stack<char> OPTR;stack<int> OPND;//设OPTR和OPND分别为运算符栈和运算数栈OPTR.push('#'); //出栈时的结尾判断char c,op1,op2,op;int x,y,temp=1;cout<<"输入表达式,以'#'结束:";cin>>c;while(c!='#'||OPTR.top()!='#'){Tonumber(c,OPND);if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='('&&c!=')'&&c!='#'){OPND.push(c);cin>>c;}else{op1=OPTR.top();op2=c;switch(Precede(op1,op2)){case '<': //栈顶元素优先级低OPTR.push(c);cin>>c;break;case '=': //脱括号并接受下一个字符OPTR.pop();cin>>c;break;case '>': op=OPTR.top(); //退栈并将运算结果入栈OPTR.pop();x=OPND.top();OPND.pop();y=OPND.top();OPND.pop();OPND.push(Operate(y,op,x));int a=OPND.top();break;}}}cout<<"计算结果是:"<<OPND.top()<<endl;return 0;}四、调试分析1、在编程过程中,为了增加程序的实用性,将程序适用范围扩大到了实数型,并增加了连续输入功能;2、在编程过程中,为了增加程序的健壮性,在运算除法时,考虑到除数为“0”时的报错和及时退出;3、在调试过程中,最初一下子出来程序就出错,为了方便检查错误,故在主函数中增加了检查后缀表达式是否转换正确的函数,并在每一步计算都跟踪结果是否正确;4、从程序实验题的编制过程中容易看出,线性表的广泛应用,特别是顺序存储结构的栈的应用。
数据结构 四则运算表达式求值 实验四报告
为后缀表达式。
(3) 计算模块:计算后缀表达式的值。
(4) 输出模块:输出后缀表达式及其计算结果。
三、详细设计
物理数据类型
因为表达式由用户输入,存储操作符和操作数的栈长度不能确定,所以使用链式堆栈存
储这些变量。
堆栈基本操作如下:
bool push(const Elem& item) //压栈
{
top=new link<Elem>(item,top);
表达式。
运算时,运算符栈顶弹栈,然后获取操作数栈顶和次栈顶的值进行运算,把运算结果创
建一个叶子结点保存,把结点压回操作数栈中。如果操作数栈或运算符栈不为空时,继续进
行运算操作。最后操作数栈中的值,就是运算结果。
程序的流程
(1) 输入模块:输入把原始的中缀表达式的操作数和操作字符存储为一个字符串。 (2) 处理模块:把字符串逐个分解,调整各项字符的顺序,分解的中缀表达式转换
EvalExpr(ch[i],S); //弹栈,运算部分
i++;
}
}
if(S.length()==1)
S.pop(result);
}
(2)、 转换实数
int EvalValue(char* ch,Stack<double> &S)
{
int i=0;
double result=0;
char a;
a=ch[i];
}
bool topValue(Elem& it) const //获取栈顶的值
{
if(size==0) return false;
it=top->elem;
return true;
(完整word版)长整数四则运算实验报告
一、需求分析设计一个实现任意长的整数间进行四则运算的程序,要求完成长整数的加、减运算,乘除运算可选做。
在这里长整数没有范围限制,可任意长。
运算后的进位、借位等都要进行正确处理,可实现动态的输入,实时的输出。
测试数据:0、0;输出“0”2345,6789、-7654,3211;输出“1,0000,0000”1,0000,0000,0000、9999,9999;输出“9999,0000,0001”1,0001,0001、;1,0001,0001;输出“0”自选数据:1,1111;1,1111 输出“0”二、概要设计1、数据结构利用双向循环链表来实现对长整数的存储。
选择该数据结构来完成长整数的加减运算是因为a.要对长整数进行运算,需要对长整数进行存储,选择用链表对长整数存储。
b.存储的顺序是从左到右,运算的顺序则是从右到左,为操作方便选择循环链表。
c.在运算过程中有进位和借位的操作。
2、使用算法三、详细设计typedef struct DoubleNode //定义链表元素void InitNode(DLNode **head) //初始化链表int InsertNode(DLNode *head,int n,DataType x) //向链表第N个位置插入元素Xint digit(int n) //判断整数N有几位void PrintNode(DLNode *head) //打印链表void DestroyNode(DLNode **head)//销毁链表void add(DLNode *h1,DLNode *h2) //两数相加void jian(DLNode *h1,DLNode *h2) //两数相减int main() //入口函数四、调试分析由于在程序设计时,对于指针的不了解,编程时使用双重指针,无形中给自己增添了更多麻烦。
老师在检查的过程中指出并教导了这一点。
五、测试结果1、输入0和0做加法运算,输出“0”,结果如下图:2、输入2345,6789和-7654,3211做减法运算,输出“1,0000,0000”,结果如下图:3、输入1,0000,0000,0000和9999,9999做减法运算,输出“9999,0000,0001”,结果如下图:4、输入1,0001,0001和1,0001,0001做减法运算,输出“0”,结果如下图:5、输入1,1111和1,1111做减法运算,输出“0”结果如下图:六、心得体会本次实验主要是针对双向链表的练习,通过这次试验我们大家对于双向循环链表有了更深刻的记忆。
数据结构实验报告——四则运算表达式求值
数据结构实验报告——四则运算表达式求值实验五四则运算表达式求值一.问题描述:四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。
二.基本要求:使用二叉树来实现。
三.实现提示:利用二叉树后序遍历来实现表达式的转换,同时可以使用实验二的结果来求解后缀表达式的值。
输入输出格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。
输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
测试实例:输入:21+23* (12-6 )输出:21 23 12 6 -*+四.设计概要用二叉树表示表达式:若表达式为数或简单变量,则相应二叉树中仅有一个根结点,其数据域存放该表达式信息若表达式= (第一操作数)(运算符)(第二操作数),则相应的二叉树中以左子树表示第一操作数,右子树表示第二操作数,根结点的数据域存放运算符(若为一元算符,则左子树空)。
操作数本身又为表达式.后缀遍历二叉树码实现和静态检查上机调试及测试数据的调试五.源程序:#include#include#include#include#include#include#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 -2using namespace std;typedef float SElemtype;typedef int Status;typedef char * TElemType;typedef struct BiTNode {TElemType data;int len; //data字符串中字符的个数struct BiTNode * lchild, * rchild;}BiTNode, *BiTree;typedef struct{SElemtype *base;SElemtype *top;int stacksize;} SqStack;Status IsDigital(char ch)if(ch>='0'&&ch<='9'){return 1; //是数字字母}return 0; //不是数字字母}int CrtNode(stack &PTR, char *c){BiTNode * T;int i=0;T = (BiTNode *)malloc(sizeof(BiTNode));T->data = (char *)malloc(DATA_SIZE*sizeof(char));while(IsDigital(c[i])){T->data [i] = c[i];i++;}T->len = i;T->lchild = T->rchild = NULL;PTR.push (T);return i;}void CrtSubTree(stack &PTR, char c){BiTNode * T;T = (BiTNode *)malloc(sizeof(BiTNode));T->data = (char *)malloc(DATA_SIZE*sizeof(char));T->data [0] = c;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) //返回符号对应优先级矩阵位置{switch(s){case '+': return 0; break;case '-': return 1; break;case '*': return 2; break;case '/': return 3; break;case '#': return 4; break;}}char Precede(char a, char b) //返回符号优先级{return(symbol[sym2num(a)][sym2num(b)]);void CrtExptree(BiTree &T, char exp[]){//根据字符串exp的内容构建表达式树Tstack PTR;//存放表达式树中的节点指针stack OPTR;//存放操作符char op;int i=0;OPTR.push ('#');op = OPTR.top();while( !((exp[i]=='#') && (OPTR.top()=='#')) ) //与{ if (IsDigital(exp[i])){//建立叶子节点并入栈PTRi+=CrtNode(PTR, &exp[i]);}else if (exp[i] == ' ')i++;else{switch (exp[i]){case '(': {OPTR.push (exp[i]);i++;break;}case ')': {op = OPTR.top (); OPTR.pop ();while(op!='('){CrtSubTree(PTR, op);op = OPTR.top (); OPTR.pop ();}//end whilei++;break;}default: //exp[i]是+ - * /while(! OPTR.empty ()){op = OPTR.top ();if (Precede(op, exp[i])=='>'){CrtSubTree(PTR, op);OPTR.pop ();}if(exp[i]!='#'){OPTR.push (exp[i]);i++;}break;}}//end switch}//end else}//end whileT = 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计数器的值。
长整数四则运算实验报告
数据结构课内实验报告书一、实验题目:长整数四则运算二、实验目的:通过本次实验,熟练掌握链表的存储结构及其各种基本运算,体会链表操作的特点。
三、实验要求:设计一个实现任意长的整数进行加法运算的演示程序。
要求:利用双向循环链表实现长整数的存储,每个结点含一个整形变量。
任何整形变量的范围是-(215 - 1)~(215 - 1)。
输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。
四、测试数据:(1)0;0;应输出“0”。
(2)-2345,6789;-7654,3211;应输出“-1,0000,0000”。
(3)-9999,9999;1,0000,0000,0000;应输出“9999,0000,0001”。
(4)1,0001,0001;-1,0001,0001;应输出“0”。
(5)1,0001,0001;-1,0001,0000;应输出“1”。
(6)-9999,9999,9999;-9999,9999,9999;应输出“1,9999,9999,9998”。
(7)1,0000,9999,9999;1;应输出“1,0001,0000,0000”。
五、设计与实现过程(1)存储结构的定义typedef struct int72 {int i[4];} INT72;INT72 a,b,c;typedef struct LinkNode{int data; //记录每个节点的整数(小于10000)LinkNode *next, *pre; //记录下一个节点的地址 *pre; //记录前一个节点的地址}linklist;(2)主要算法的描述void addtwo()//节点多的作为被加数,少的作为加数,实现整数绝对值大的加小的//默认head0存的整数绝对值比head1大{int s=0,m1=head0->data,m2=head1->data;m1=(head0->pre->data/abs(head0->pre->data)); //head0的符号m2=(head1->pre->data/abs(head1->pre->data)); //head1的符号linklist *p=head0->pre->pre,*q=head1->pre->pre;result->data=head0->pre->data; //存结果的节点数和符号while(q!=head1->pre)//head0存的整数绝对值比head1大,即head0的节点数大于或等于head1 {currptr=(linklist *)malloc(sizeof(linklist));currptr->data=(p->data)*m1+(q->data)*m2+s; //两整数相加if((m1*m2)>0) //如果符号相同{if(abs(currptr->data)-10000>=0) //相加后超过10000,则进位{s=currptr->data/10000;currptr->data=abs(currptr->data)%10000;}else //abs(currptr->data)-10000<0,不进位{s=0;currptr->data=abs(currptr->data);}}else if(m1>0&&m2<0)//符号不同,在此相当于实现两个正整数相减{s=0;if(currptr->data<0) //小于0,向前一位借1{currptr->data+=10000;s=-1;}}else if(m1<0&&m2>0)//符号不同,在此相当于实现负整数加上正整数{s=0;if(currptr->data>0) //大于0,{currptr->data=10000-currptr->data;s=1;}else currptr->data=abs(currptr->data);}currptr->next=result; //存入链表currptr->pre=result->pre;result->pre->next=currptr;result->pre=currptr;result=currptr;p=p->pre;q=q->pre;}//当head0节点数比head1长时,继续建链while(p!=head0->pre){currptr=(linklist *)malloc(sizeof(linklist)); currptr->data=p->data+s;s=currptr->data/10000;if((m1*m2)>0){if(abs(currptr->data)-10000>=0){s=currptr->data/10000;currptr->data=abs(currptr->data)%10000;}else {s=0;currptr->data=abs(currptr->data);} }else if(m1>0&&m2<0){s=0;if(currptr->data<0){currptr->data+=10000;s=-1;}}else if(m1<0&&m2>0){s=0;if(currptr->data>0){currptr->data=10000-currptr->data;s=1;}else currptr->data=abs(currptr->data);}currptr->data=abs(currptr->data)%10000; currptr->next=result;currptr->pre=result->pre;result->pre->next=currptr;result->pre=currptr;result=currptr;p=p->pre;}if(s!=0) //处理相加后,进位问题{currptr=(linklist *)malloc(sizeof(linklist));currptr->data=abs(s);currptr->next=result;currptr->pre=result->pre;result->pre->next=currptr;result->pre=currptr;result=currptr;result->pre->data=m1*(abs(result->pre->data)+1);}}六、技巧与体会在编写程序中尽量做到独立完成、对于自己想要完成的问题要主动编程完成、这样自己是一个很大的提升、也能学到很多的知识、熟练编程!以后要加强动手时间能力、多与同学交流算法精髓!。
表达式求值 实验报告
表达式求值实验报告表达式求值实验报告一、引言表达式求值是计算机科学中一个重要的概念,它涉及到对数学表达式的计算和求解。
在本次实验中,我们将探讨表达式求值的相关算法和实现方法,并通过编程实现一个简单的表达式求值器。
二、算法原理1. 表达式的表示方法在计算机中,我们通常使用字符串来表示表达式。
例如,一个简单的数学表达式"2 + 3 * 4"可以表示为字符串"2+3*4"。
在实现表达式求值的算法时,我们需要将字符串中的数字和运算符进行分离,以便进行后续的计算。
2. 中缀表达式转后缀表达式为了方便计算,我们通常将中缀表达式转换为后缀表达式。
后缀表达式也称为逆波兰表达式,它的特点是运算符位于操作数的后面。
例如,上述的中缀表达式"2+3*4"可以转换为后缀表达式"234*+"。
转换的方法可以通过使用栈来实现。
3. 后缀表达式求值得到后缀表达式后,我们可以通过扫描表达式并使用栈来求解。
当遇到操作数时,将其压入栈中;当遇到运算符时,从栈中弹出相应数量的操作数进行计算,并将结果压入栈中。
最终,栈中的唯一元素即为表达式的求值结果。
三、实验过程1. 数据结构设计为了实现表达式求值器,我们需要设计相应的数据结构。
在本次实验中,我们选择使用栈来存储操作数和运算符。
2. 中缀表达式转后缀表达式首先,我们需要编写一个函数来将中缀表达式转换为后缀表达式。
该函数的实现可以通过使用栈和遍历字符串来实现。
具体的步骤如下:- 创建一个空栈和一个空字符串用于存储后缀表达式。
- 从左到右遍历中缀表达式的每个字符。
- 如果遇到操作数,直接将其添加到后缀表达式字符串中。
- 如果遇到运算符,将其与栈顶的运算符进行比较:- 如果栈为空或栈顶为左括号"(",则直接将运算符入栈。
- 如果栈顶的运算符优先级低于当前运算符,则将当前运算符入栈。
- 如果栈顶的运算符优先级高于或等于当前运算符,则将栈顶的运算符弹出并添加到后缀表达式字符串中,直到栈顶的运算符优先级低于当前运算符或栈为空。
四则运算表达式求值
HUNAN UNIVERSITY背景在工资管理软件中,不可避免的要用到公式的定义及求值等问题。
对于数学表达式的计算,虽然可以直接对表达式进行扫描并按照优先级逐步计算,但也可以将中缀表达式转换为逆波兰表达式,这样更容易处理。
问题描述四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。
一.需求分析(1)本程序利用二叉树后序遍历来实现表达式的转换,同时可以使用栈来求解后缀表达式的值。
(2)输入输出的格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。
输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式和计算结果,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
(3)测试用例:输入:21+23*(12-6)+9输出:21 23 12 6 -*+ 9+result is 168二.概要设计(1)抽象数据类型:由于四则运算表达式中运算符可能有多个后继,而运算的对象无后继,可以采用二叉树来实现把中缀表达式转换为后缀表达式。
数据对象:四则运算符及整数数据关系:运算符有多个后继,二运算对象的值无后继基本操作:后序遍历,二叉树的构建和摧毁,插入,删除经过二叉树的后序遍历后的表达式惊醒运算是满足后进先出的原则,采用栈来实现四则运算表达式的求值。
数据对象:运算符(字符)及整数数据关系:后进先出基本操作:入栈,出栈,栈的构建和删除(2)算法基本思想:用二叉树来存储四则表达式,再通过后序遍历把中缀表达式转换为后缀表达式,最后通过栈来计算表达式的值,最后输出后序表达式和表达式的值。
(3)程序的流程:该程序有三个模块组成:1.输入模块:输入一个中缀表达式2.处理模块:把中缀表达式转换为后缀表达式3.计算模块:计算表达式的值4.输出模块:输出后缀表达式及表达式的值三.详细设计(1)物理数据类型:采用指针来实现二叉树,其中分支节点存储运算符,用叶子节点存储操作数,可以减少二叉树的结构性开销。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HUNAN UNIVERSITY 课程实习报告
题目:四则运算表达式求值
学生姓名:
学生学号:
专业班级:
指导老师:
完成日期:
一、需求分析
四则运算表达式求值,将四则运算表达式用中缀表达式表示,然后转换为后缀表达式,并计算结果。
本程序要求利用二叉树后序遍历来实现表达式的转换,同时可以使用实验2的结果来求解后缀表达式的值。
在字符界面上输入一个中缀表达式,回车表示结束。
如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
测试数据
输入:
21+23*(12-6)
输出:
21 23 12 6 -*+
二、详细设计
输入和输出的格式
输入
本程序可以将输入的四则运算表达式(中缀表达式)转换为后缀表达式
输出
后缀表达式为://输出结果的位置
表达式的值为://输出结果的位置
三、调试分析
本次实验的难点主要是在建立二叉树的问题上。
关于如何把中缀表达式存入二叉树中,我参考了网上的一些方法,成功实现了目标,但是却遇到了一个问题,那就是不能处理小数,甚至两位或两位以上的整数。
因为如果采用字符数组来存储操作数,运算符合一位整数还可以处理,但对于两位数就就会出问题,最后我改进采用字符串数组来存储操作数,成功解决了问题。
另外在处理输入的非法表达式问题中,我也费了很大功夫,但总体问题不大。
四、测试结果
五、用户使用说明(可选)
1、运行程序时
提示输入四则运算表达式
本程序可以将中缀表达式转化为后缀表达式,并计算结果
请输入四则运算表达式:
输出
后缀表达式为:
表达式的值为:
程序源代码(c++)
#include<iostream>
#include<string>
#include<stack>
#include<iomanip>
const int Max=100;
using namespace std;
class Node{
public:
char ch[Max]; //考虑到数值有时会是两位数,所以使用字符串数组
Node* lChild;
Node* rChild;
Node(){
strcpy(ch,"");
lChild=rChild=NULL;
}
~Node(){
if(lChild!=NULL)
delete lChild;
if(rChild!=NULL)
delete rChild;
}
};
static int count=0;
static char array[Max]; //保存原始的中缀表达式
static char str[2*Max]; //保存后序遍历出来的字符串,为表达式求值提供方便static int k=0;
char getOp(Node *temp); //temp指针保存每个结点,返回的是运算符
Node* crtTree(Node* root); //传入根结点指针,返回根结点指针
void output(Node *root); //获得处理后的字符串
bool isError(char); //判断字符是否有问题
void deal(); //对字符数组进行处理
double value(string); // 计算后缀表达式,得到其结果。
int main(){
Node* root=NULL;
cout<<"输入中缀表达式:";
cin.getline(array,40);
deal();
root=crtTree(root);
cout<<"输出后缀表达式:";
output(root);
cout<<str<<endl;
cout<<"输出后缀表达式的值:";
if(value(str)!=0)
cout<<fixed<<setprecision(2)<<value(str)<<endl;
else
cout<<"A Wrong Input!"<<endl;
return 0;
}
//将数字字符存入一个结点,并返回数字字符的后一个符号char getOp(Node *temp){
int i=0;
if( isError(array[count]) )
exit(0);
while(array[count]<='9'&&array[count]>='0'||array[count]=='.'){ temp->ch[i]=array[count];
i++;
count++;
}
temp->ch[i]='\0';
count++;
return array[count-1];
}
//传入根结点指针,返回根结点指针
Node* crtTree(Node* root) {
Node *p,*q;
char op;
if(root==NULL){
root=new Node;
p=new Node;
}
op=getOp(root);
while(op!='='){
q=new Node;
q->ch[0]=op;
q->ch[1]='\0';
switch(op)
{
case '+':
case '-':
q->lChild=root;
root=q;
p=new Node;
op=getOp(p);
root->rChild=p;
break;
case '*':
case '/':
if(root->ch[0]=='+'||root->ch[0]=='-'){
p=new Node;
strcpy(p->ch,root->ch);
p->lChild=root;
p->rChild=q;
op=getOp(root);
root=p;
} else {
q->lChild=root;
root=q;
p=new Node;
op=getOp(p);
root->rChild=p;
} break;
case '(':
p=root;
while(p->rChild)
p=p->rChild;
if(p->lChild==NULL) {
p->lChild=crtTree(p->lChild); //递归创建括号里的指针
op=array[count];
count++;
break;
} else{
p->rChild=crtTree(p->rChild); //递归创建括号里的指针
op=array[count];
count++;
break;
}
case ')':
return root;
}
}
return root;
}
//传入根结点,后序遍历,赋值给另一个字符数组(主要是为了给后序的计算表达式值提供方便)
void output(Node *root){
int n;
if(root){
output(root->lChild);
output(root->rChild);
n=0;
while(root->ch[n]!='\0')
str[k++]=root->ch[n++];
str[k++]=' ';
}。