c语言数据结构算术表达式求值
算术表达式求值数据结构代码
#include <iostream>#include<stdio.h>#include<stdlib.h>#include<malloc.h>#include<string.h>using namespace std;#define OK 1#define ERROR 0#define OVERFLOW -2#define STACK_SIZE 100#define STACKINCREMENT 10#define OPSIZE 7typedef double ElemType;typedef char SElemType;char op[OPSIZE]={'+','-','*','/','(',')','#'};charprior[OPSIZE][OPSIZE]={{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},{'>','>',' >','>','<','>','>'},{'<','<','<','<','<','=',' '},{'>','>','>','>',' ','>','>'},{'<','<','<','<','<',' ','='}};typedef struct {ElemType *top;ElemType *base;int Stacksize;}OPND;typedef struct {SElemType *top;SElemType *base;int Stacksize;}OPTR;void InitStack(OPND *S1){S1->base=(ElemType *)malloc(STACK_SIZE * sizeof(ElemType));if(NULL==S1->base){printf("Init Failed!\n");exit (OVERFLOW);}else{S1->top=S1->base;S1->Stacksize=STACK_SIZE;}}int StackEmpty(OPND *S1){if(S1->top==S1->base)return 1;elsereturn 0;}int StackEmpty(OPTR *S2){if(S2->top==S2->base)return 1;elsereturn 0;}void InitStack(OPTR *S2){S2->base=(SElemType *)malloc(STACK_SIZE*sizeof(SElemType));if(NULL==S2->base){printf("Init Failed!\n");exit (OVERFLOW);}else{S2->top=S2->base;S2->Stacksize=STACK_SIZE;}}void Push(OPND *S1,ElemType e){if(S1->top-S1->base>=S1->Stacksize){S1->base=(ElemType*)realloc(S1->base,(S1->Stacksize+STACKINCREMENT)*sizeof(ElemType));if(!S1->base)exit(OVERFLOW);S1->top=S1->base+S1->Stacksize;S1->Stacksize=S1->Stacksize+STACKINCREMENT;}*S1->top=e;S1->top++;}void Push(OPTR *S2,SElemType e){if(S2->top-S2->base>=S2->Stacksize){S2->base=(SElemType*)realloc(S2->base,(S2->Stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S2->base)exit (OVERFLOW);S2->top=S2->base+S2->Stacksize;S2->Stacksize+=STACKINCREMENT;}*S2->top++=e;}ElemType Pop(OPND *S1,ElemType *e){if(!StackEmpty(S1)){S1->top=S1->top-1;*e=*S1->top;}else{return ERROR;}return OK;}SElemType Pop(OPTR *S2,SElemType *e){if(StackEmpty(S2)){return ERROR;}else{*e=*--S2->top;}return OK;}ElemType GetTop(OPND *S1,ElemType *e){if(!StackEmpty(S1)){*e=*(S1->top-1);}return OK;}SElemType GetTop(OPTR *S2,SElemType *e){if(!StackEmpty(S2)){*e=*(S2->top-1);}return OK;}bool Judege(char c,char *op)//判断C是否为运算符{bool check=false;int i;for(i=0;i<OPSIZE;i++){if(c==op[i]){check = true;}}return check;}int ReturnOpOrd(char c,char *op)//返回运算符c在OP中的位置{int i;for(i=0;i<OPSIZE;i++){if(c==op[i]){return i;}}return OK;}char Precede(char theat1,char theat2)//g判断运算符栈的栈顶运算符theta1和读入的运算符theta2优先关系{return prior[ReturnOpOrd(theat1,op)][ReturnOpOrd(theat2,op)];}double Operate(ElemType a,SElemType theat,ElemType b)//操作数进行运算{switch(theat){case '+':return a+b;break;case '-':return a-b;break;case '*':return a*b;break;case '/':if(b!=0){return a/b;}else{printf("出错!除数为0!\n");return ERROR;}break;default:return 0;}}float EvaluateExpression(char *expression){OPND S1;OPTR S2;char *c=expression;ElemType e1,e2,result,d;char temp[10],r[2];SElemType e;InitStack(&S1);InitStack(&S2);Push(&S2,'#');strcpy(temp,"\0");while(*c!='#'||((GetTop(&S2,&e),e))!='#'){if(!Judege(*c,op)){r[0]=*c;r[1]='\0';strcat(temp,r);c++;if(Judege(*c,op)){d=(float)atof(temp);Push(&S1,d);strcpy(temp,"\0");}}else{switch(Precede( (GetTop(&S2,&e),e),*c)){case '<':Push(&S2,*c);c++;break;case '=':Pop(&S2,&e);c++;break;case '>':Pop(&S1,&e1);Pop(&S1,&e2);Pop(&S2,&e);result=Operate(e2,e,e1);Push(&S1,result);break;}}}Pop(&S1,&result);return result;}int main(){char expression[80];float result;printf("输入你要计算的算式:\n");gets(expression);result=EvaluateExpression(expression);printf("计算结果为:%f",result);return OK;}。
数据结构-算术表达式求值(含需求分析和源代码)
需求分析(附代码)一、需求分析(1)首先定义两个栈OPTR、OPND,栈OPTR用于存放运算符,栈OPND 用于存放操作数;定义一个一维数组expr【】存放表达式串。
(2)主函数主要包括两部分:(1)判断运算符优先权,返回优先权高的;(2)操作函数。
(3)开始将‘#’入操作符栈,通过一个函数来判别算术运算符的优先级。
且规定‘#’的优先级最低。
在输入表达式的最后输入‘#’,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈。
遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
(4)最初实现的加、减、乘、除及带小括号的基本运算,但考虑到实用性,后来的设计中有加上了乘方运算。
在乘方运算中借用了C库中自带的乘方函数pow。
二、概要设计1、设定栈的抽象数据类型定义:ADT Stack {数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,n≥0 }数据关系:R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }约定an端为栈顶,a1端为栈底。
基本操作:InitStack(&S)操作结果:构造一个空栈S。
DestroyStack(&S)初始条件:栈S已存在。
操作结果:栈S被销毁。
StackEmpty(S)初始条件:栈S已存在。
操作结果:若栈S为空栈,则返回TRUE,否则FALE。
StackLength(S)初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度。
GetTop(S, &e)初始条件:栈S已存在且非空。
操作结果:用e返回S的栈顶元素。
ClearStack(&S)初始条件:栈S已存在。
c语言算术表达式求值
c语言算术表达式求值C语言是一种广泛应用的编程语言,其强大的算术表达式求值功能使其在科学计算、数据处理、游戏开发等领域有着重要的应用。
本文将介绍C语言中算术表达式求值的相关知识,包括运算符、运算符优先级、表达式求值的顺序等内容。
我们需要了解C语言中常用的算术运算符。
C语言支持的算术运算符包括加法(+)、减法(-)、乘法(*)、除法(/)和求余(%)等。
这些运算符用于对数值进行基本的加减乘除运算。
在C语言中,运算符的优先级决定了表达式求值的顺序。
常见的运算符优先级从高到低依次为:1. 括号(()):括号中的表达式具有最高的优先级,可以改变默认的运算次序。
2. 一元运算符:包括正号(+)和负号(-),用于表示正负数。
3. 乘法、除法和求余:乘法(*)、除法(/)和求余(%)的优先级相同,从左到右依次计算。
4. 加法和减法:加法(+)和减法(-)的优先级相同,从左到右依次计算。
在使用C语言进行算术表达式求值时,我们需要遵循这些运算符的优先级规则,以保证表达式的正确求值。
如果表达式中包含多个运算符,我们需要根据优先级确定运算的顺序,可以使用括号来改变默认的运算次序。
下面我们将通过几个例子来说明C语言中算术表达式求值的过程。
例1:求解一个简单的算术表达式假设我们需要计算表达式 3 + 4 * 2,根据运算符优先级规则,先计算乘法,再计算加法。
具体的求解过程如下:1. 计算4 * 2,得到8。
2. 计算3 + 8,得到11。
所以,表达式3 + 4 * 2的值为11。
例2:使用括号改变运算次序假设我们需要计算表达式(3 + 4) * 2,根据运算符优先级规则,先计算括号内的加法,再计算乘法。
具体的求解过程如下:1. 计算3 + 4,得到7。
2. 计算7 * 2,得到14。
所以,表达式(3 + 4) * 2的值为14。
通过以上两个例子,我们可以看到,C语言中的算术表达式求值是按照运算符优先级和运算次序进行的,遵循从左到右的计算规则。
c_语言_算术表达式的求值__数据结构_课程设计
//算术表达式的求值//济南大学信息学院计算机数据结构课程设计/*【问题描述】表达式计算式实现程序设计语言的的基本问题之一,也是栈的应用的一个典型例子,设计一个程序,演示用运算符优先法对算术表达式的求值的过程。
*///main.cpp#include "iostream.h"#include "stdlib.h"#include "public.h"#include "stack.h"//using namespace std;LinkStack OPTR;//操作符栈int Allnum[100]={0}; //储存所有的运算数int NUM[100]={0};//操作数栈int n=0;void calcu(){int x1,x2,x;char p;//弹出一个运算符Pop(OPTR,p);//弹出两个操作数x2=NUM[n--];x1=NUM[n--];//进行一次运算switch(p) {case '+':x=x1+x2;break;case '-':x=x1-x2;break;case '*':x=x1*x2;break;case '/':x=x1/x2;//结果压入操作数栈NUM[++n]=x;}int EvaluateExpression(char *p){InitStack(OPTR);InitStack(OPND);int i=0;char temp;int num=0;while( *p!='\0' )switch(*p){case '+': case '-':while ( (GetTop(OPTR,temp))!=ERROR && (temp!='('))//执行先遇到的加、减运算calcu();//当前运算符进栈Push(OPTR,*p);//读下一个字符p++;break;case '*': case '/':if ( GetTop(OPTR,temp)==OK && (temp=='*') || (temp=='/')) //执行先遇到的乘、除运算calcu();//当前运算符进栈Push(OPTR,*p);//读下一个字符p++;break;case '('://左括号进栈Push(OPTR,*p);//读下一个字符p++;break;case ')':while ( GetTop(OPTR,temp)==OK && temp!='(' )//执行括号内的加、减、乘、除运算calcu();//弹出左括号char e;Pop(OPTR,e);//读下一个字符p++;break;default://把字符串转换成整数值//int num=strInt(p);num=0;do {num=10*num+*p-'0';p++;} while((*p>='0')&&(*p<='9'));//char strnum[10];//NumString(num,strnum);//将num转换为字符串strnum//操作数进栈NUM[++n]=num;//s1[++t1]=v;Allnum[i++]=num;};while ( GetTop(OPTR,temp)==OK )calcu();//返回结果//printf("%d \n",NUM[1]);return NUM[n];}//EvaluateExpressionvoid main(){char a[100];//="5+(9-2*3)^2+3*(2+1)"; //="5*(40+6)-39";5+(9-2*3)^2+3*(2+1)int i=0;start:cout<<"算数表达式:_" ;cin>>a;cout<<EvaluateExpression(a)<<endl;//system("pause");cout<<"----------------"<<endl;goto start;}//public.henum Status{OK,ERROR,}; //定义枚举类型int strInt(char *p){//把字符串转换成整数值int num=0;do {num=10*num+*p-'0';p++;} while((*p>='0')&&(*p<='9'));return num;}///////////数字转换字符串void convert(int abc,char a[],int &i_num){if( abc/10!=0 )convert(abc/10,a,i_num);a[i_num]=abc%10+'0';i_num++;}void NumString(int abc,char a[]){if(abc<0) abc=-abc;int i_num=0;convert(abc,a,i_num);a[i_num]='\0';}//////////////////stack.h//typedef char char;typedef struct SNode{char data; //数据域struct SNode *next; //指针域}SNode,*LinkStack; //定义链栈结点Status InitStack( LinkStack &S ){//将S初始化为一个空的链栈S=( LinkStack ) malloc ( sizeof( SNode ) );if( S==NULL ) return ERROR; //内存空间申请不成功S->next=NULL;return OK;}Status DestroyStack(LinkStack &S){//销毁栈SLinkStack p;while(S->next){p=S->next;S->next=p->next;free(p);}free(S);return OK;}Status StackIsEmpty(LinkStack S){//判断栈是否为空if (S->next==NULL) return OK;return ERROR;}Status Push(LinkStack &S, char e){//将数据元素e插入到栈S的栈顶LinkStack p;p=( LinkStack ) malloc ( sizeof( SNode ) );if( p==NULL ) return ERROR;p->data=e;p->next=NULL; //创建新结点p->next=S->next;S->next=p; //插入return OK;}Status Pop(LinkStack &S, char &e){//将栈S的栈顶元素出栈,并存放到e中LinkStack p;if( S->next==NULL ) return ERROR; //空队出错p=S->next; //记住要删除的结点S->next=p->next; //栈顶元素p出栈e=p->data;free(p); //释放存储空间return OK;}Status GetTop(LinkStack S, char &e){LinkStack p;//char e;if( S->next==NULL ) return ERROR; //空队出错p=S->next;e=p->data;return OK;}。
数据结构 算术表达式求值
/**************************************************************************** 2、算术表达式求值(必做) (栈)时间:2012年12月[问题描述]一个算术表达式是由操作数( operand)、运算符(operator )和界限符(delimiter)组成的。
假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“# ”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
[基本要求](1)从键盘或文件读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
(3)考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。
***************************************************************************/ #include <stdio.h>#include <stdlib.h>#include <string.h>#define OVERFLOW 0#define ERROR 0#define OK 1#define STACK_INIT_SIZE 100 //存储空间初始分配量#define STACKINCREMENT 10 //存储空间分配增量#define MAXSIZE 100#define N 100//*********************************************************************** struct expression{double result;char expstr[MAXSIZE];}exp;typedef struct{char *base; //在栈构造之前和销毁之后,base的值为NULLchar *top; //操作符栈栈顶指针int stacksize; //当前已分配的存储空间,以元素为单位}StackOPTR;//操作符栈typedef struct{float *base; //在栈构造之前和销毁之后,base的值为NULLfloat *top; //操作数栈栈顶指针int stacksize; //当前已分配的存储空间,以元素为单位}StackOPND;//操作数栈//************************栈的基本操作************************************************//***初始化***void InitStack(StackOPTR &S)//操作符栈初始化{S.base=(char *)malloc(STACK_INIT_SIZE * sizeof(char));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;}void InitStack(StackOPND &S)//操作数栈初始化{S.base=(float *)malloc(STACK_INIT_SIZE * sizeof(float));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;}//***GetTop***int GetTop(StackOPTR S,char &e)//若操作符栈不空,则用e返回s的栈顶元素{if(S.top==S.base)return ERROR;e=*(S.top-1);return OK;}int GetTop(StackOPND S,float &e)//若操作数栈不空,则用e返回s的栈顶元素{if(S.top==S.base)return ERROR;e=*(S.top-1);return OK;}//***Push***void Push(StackOPTR &S,char e)//插入元素e为新的操作符栈顶元素{if(S.top-S.base>=S.stacksize){S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;}void Push(StackOPND &S,float e)//插入元素e为新的操作数栈顶元素{if(S.top-S.base>=S.stacksize){S.base=(float*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(float));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;}//***Pop***int Pop(StackOPTR &S,char &e)//若操作符栈不空,删除s的栈顶元素,用e返回其值{if(S.top==S.base)return ERROR;e=*--S.top;return OK;}int Pop(StackOPND &S,float &e)//若操作数栈不空,删除s的栈顶元素,用e返回其值{if(S.top==S.base)return ERROR;e=*--S.top;return OK;}#define OPSIZE 7//运算符个数char OP[OPSIZE]={'+','-','*','/','(',')','#'};//运算符集合// 表3.1 算符间的优先关系char Prior[7][7] ={'>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>','<','<','<','<','<','=',' ','>','>','>','>',' ','>','>','<','<','<','<','<',' ','='};//***int In(char c,char *OP)//OP是运算符集合,检验是否为运算符{bool check=false;for(int i=0;i<OPSIZE;i++){if(c==OP[i])check=true;}return check;}//***float Operate(float a,char theta,float b)//进行二元运算aeb {switch(theta){case'+':return a+b;break;case'-':return a-b;break;case'*':return a*b;break;case'/':if(b==0){printf("不得出现0作为除数!\n");return 0;}elsereturn a/b;break;default:return 0;}}//***int Xu_Op(char theta,char *OP)//返回运算符c在OP中的序号{int i;for(i=0;i<OPSIZE;i++){if(theta==OP[i])return i;}return 0;}char Precede(char theta1,char theta2)//判断运算符栈的栈顶运算符theta1和读入的运算符theta2优先关系{return Prior[Xu_Op(theta1,OP)][Xu_Op(theta2,OP)];}//****算法健壮性的检查*******int change(char c)//字符都改成编号{switch(c){case'(': return 0;break;case'#': return 1;break;case')': return 2;break;case'+': return 3;break;case'-': return 3;break;case'*': return 4;break;case'/': return 4;break;case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9': return -1;break;default: return -2;}}int Wrong(char *exp)//检查算法的健壮性{char *p,*q;int i=0;//记录括号,i=0,合法。
c语言算术表达式求值
c语言算术表达式求值【实用版】目录1.引言2.C 语言算术表达式的基本概念3.C 语言算术表达式的求值方法4.实际应用示例5.总结正文【引言】在 C 语言编程中,算术表达式是用来进行数值计算的重要工具。
本篇文章将为大家介绍 C 语言算术表达式的求值方法。
【C 语言算术表达式的基本概念】C 语言中的算术表达式主要包括以下几种:1.一元运算符:例如+、-、*、/等,用于对一个数值进行操作。
2.二元运算符:例如+、-、*、/等,用于对两个数值进行操作。
3.关系运算符:例如<、>、<=、>=、==、!=等,用于比较两个数值的大小或相等性。
4.逻辑运算符:例如&&、||、! 等,用于进行逻辑判断。
【C 语言算术表达式的求值方法】C 语言中,算术表达式的求值主要遵循以下规则:1.先进行括号内的运算,再进行括号外的运算。
2.先进行乘除法运算,再进行加减法运算。
3.关系运算符和逻辑运算符的优先级较低,从左到右依次进行运算。
【实际应用示例】下面我们通过一个实际的 C 语言程序,来演示算术表达式的求值过程。
```c#include <stdio.h>int main() {int a = 10, b = 5;int result;result = a + b * (a - b) / (a * b);printf("The result is: %d", result);return 0;}```在这个程序中,我们定义了两个整数变量 a 和 b,并通过算术表达式计算 result 的值。
根据我们之前提到的算术表达式求值规则,我们可以将这个表达式分解为以下几个步骤:1.计算括号内的值:a - b = 10 - 5 = 52.计算乘法运算:b * (a - b) = 5 * 5 = 253.计算除法运算:(a * b) / (a * b) = 14.计算加法运算:a + 25 = 10 + 25 = 355.输出结果:printf("The result is: %d", result); 输出 35【总结】通过本篇文章的介绍,相信大家已经对 C 语言算术表达式的求值方法有了更加深入的了解。
数据结构课程设计-表达式求值【完整版】
XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序得主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式就是由操作数(operand)、运算符(operator)与界限符(delimiter)组成得。
假设操作数就是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号与表达式起始、结束符“#”,如:#(7+15)*(23—28/4)#。
引入表达式起始、结束符就是为了方便.编程利用“算符优先法”求算术表达式得值.二、程序得主要功能(1)从键盘读入一个合法得算术表达式,输出正确得结果。
(2)显示输入序列与栈得变化过程。
三、程序运行平台Visual C++6、0版本四、数据结构本程序得数据结构为栈。
(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针intstacksize; //栈得长度};intInitStack (SqStack &s) //建立一个空栈S{if (!(s、base= (char *)malloc(50*sizeof(char))))exit(0);s、top=s、base;s、stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s、top==s、base) //栈为空得时候返回ERROR{ﻩ printf("运算符栈为空!\n");ﻩ return ERROR;}elsee=*(s、top-1); //栈不为空得时候用e做返回值,返回S得栈顶元素,并返回OK returnOK;}int Push(SqStack&s,char e) //运算符入栈{if (s、top—s、base >= s、stacksize)ﻩ{printf("运算符栈满!\n");ﻩs、base=(char*)realloc(s、base,(s、stacksize+5)*sizeof(char));//栈满得时候,追加5个存储空间if(!s、base)exit (OVERFLOW);s、top=s、base+s、stacksize;s、stacksize+=5;}ﻩ*(s、top)++=e;//把e入栈ﻩreturn OK;}int Pop(SqStack &s,char &e) //运算符出栈{if (s、top==s、base) //栈为空栈得时候,返回ERROR{printf("运算符栈为空!\n”);ﻩ return ERROR;}else{ﻩﻩe=*-—s、top;//栈不为空得时候用e做返回值,删除S得栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack&s)//运算符栈得遍历{ﻩchar *t;ﻩt=s、base;ﻩif (s、top==s、base){ﻩ printf(”运算符栈为空!\n”); //栈为空栈得时候返回ERRORreturn ERROR;}while(t!=s、top){ﻩﻩprintf(" %c",*t); //栈不为空得时候依次取出栈内元素t++;ﻩ}return ERROR;}(2)数字栈部分:struct SqStackn//定义数栈{int *base; //栈底指针int*top; //栈顶指针int stacksize; //栈得长度};intInitStackn (SqStackn &s) //建立一个空栈S{s、base=(int*)malloc(50*sizeof(int));if(!s、base)exit(OVERFLOW);//存储分配失败s、top=s、base;s、stacksize=50;return OK;}int GetTopn(SqStackn s,int&e) //数栈取栈顶元素{if(s、top==s、base){printf("运算数栈为空!\n");//栈为空得时候返回ERRORﻩ return ERROR;}elseﻩe=*(s、top-1);//栈不为空得时候,用e作返回值,返回S得栈顶元素,并返回OKreturnOK;}int Pushn(SqStackn &s,int e) //数栈入栈{if(s、top—s、base>=s、stacksize){ﻩﻩprintf("运算数栈满!\n");//栈满得时候,追加5个存储空间ﻩs、base=(int*)realloc (s、base,(s、stacksize+5)*sizeof(int));if(!s、base) exit (OVERFLOW);ﻩs、top=s、base+s、stacksize;//插入元素e为新得栈顶元素s、stacksize+=5;}*(s、top)++=e; //栈顶指针变化returnOK;}int Popn(SqStackn &s,int &e)//数栈出栈{ﻩif (s、top==s、base){ﻩ printf("运算符栈为空!\n");//栈为空栈得视时候,返回ERRORﻩ return ERROR;ﻩ}else{ﻩﻩe=*—-s、top;//栈不空得时候,则删除S得栈顶元素,用e返回其值,并返回OK ﻩreturnOK;}}int StackTraversen(SqStackn &s)//数栈遍历{ﻩint*t;ﻩt=s、base ;ﻩif(s、top==s、base)ﻩ{printf("运算数栈为空!\n”);//栈为空栈得时候返回ERRORﻩ return ERROR;ﻩ}ﻩwhile(t!=s、top)ﻩ{printf(” %d”,*t); //栈不为空得时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。
c语言数据结构算术表达式求解
C语言是一种广泛应用的程序设计语言,它具有丰富的库函数和灵活的数据结构,因此在算术表达式求解方面具有较强的优势。
本文将对C语言在算术表达式求解方面的应用进行介绍和探讨。
一、算术表达式的定义和基本规则1. 算术表达式是由数字、运算符和括号组成的式子,用来表示数学运算关系。
2. 算术表达式求解的基本规则是遵循数学运算规律,如乘除优先于加减,括号内先计算等。
二、C语言中的数据结构1. 在C语言中,数据结构是由数组、链表、栈、队列等构成的数据组织形式,用来存储和处理数据。
2. 数据结构在C语言中具有丰富的功能和灵活的应用方式,可以用来表示和操作各种类型的数据。
三、C语言中的算术表达式求解方法1. 使用栈来实现算术表达式的求解是C语言中常见的方法之一。
栈是一种具有先进后出特性的数据结构,适合用来处理括号匹配和运算符优先级等问题。
2. 利用栈来实现算术表达式求解的基本步骤是将中缀表达式转换为后缀表达式,然后利用后缀表达式进行运算求解。
四、C语言中的算术表达式求解实例1. 以下是一个简单的算术表达式求解实例,以便更好地理解C语言中的算术表达式求解方法。
2. 中缀表达式:2 * (3 + 4) - 53. 转换为后缀表达式:2 3 4 + * 5 -4. 求解后缀表达式得到结果:9五、C语言中的算术表达式求解函数1. 在C语言中,可以通过编写求解算术表达式的函数来实现对算术表达式的求解。
2. 以下是一个简单的算术表达式求解函数的示例:```c#include <stdio.h>#include <stdlib.h>typedef int ElementType;typedef struct Node *PtrToNode;struct Node{ElementType Data;PtrToNode Next;};typedef PtrToNode Stack;int IsEmpty(Stack S){return S->Next == NULL;}Stack CreateStack(void){Stack S;S = (Stack)malloc(sizeof(struct Node)); if (S == NULL){printf("Out of space\n");return NULL;}S->Next = NULL;MakeEmpty(S);return S;}void MakeEmpty(Stack S){if (S == NULL)printf("Must use CreateStack first");elsewhile (!IsEmpty(S))Pop(S);}void Push(ElementType X, Stack S){PtrToNode TmpCell;TmpCell = (PtrToNode)malloc(sizeof(struct Node)); if (TmpCell == NULL)printf("Out of space\n");else{TmpCell->Data = X;TmpCell->Next = S->Next;S->Next = TmpCell;}}ElementType Top(Stack S){if (!IsEmpty(S))return S->Next->Data;printf("Empty stack");return 0;}void Pop(Stack S){PtrToNode FirstCell;if (IsEmpty(S))printf("Empty stack");else{FirstCell = S->Next;S->Next = S->Next->Next;free(FirstCell);}}```六、C语言中的算术表达式求解的应用场景1. 算术表达式求解在C语言编程中具有广泛的应用场景,如编写计算器程序、处理数学公式、实现科学计算等。
数据结构实验报告-算术表达式求值
- - 1.前言12.概要设计12.1 数据构造设计12.2 算法设计12.3 ADT描述22.4 功能模块分析23.详细设计33.1 数据存储构造设计33.2主要算法流程图〔或算法伪代码〕44.软件测试75.心得体会8参考文献8附录9- -优质-..1.前言在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进展。
因而在程序设计时,借助栈实现。
算法输入:一个算术表达式,由常量、变量、运算符和括号组成〔以字符串形式输入〕。
为简化,规定操作数只能为正整数,操作符为+、-*、/,用#表示完毕。
算法输出:表达式运算结果。
算法要点:设置运算符栈和运算数栈辅助分析算符优先关系。
在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。
2.概要设计2.1 数据构造设计任何一个表达式都是由操作符,运算符和界限符组成的。
我们分别用顺序栈来存放表达式的操作数和运算符。
栈是限定于紧仅在表尾进展插入或删除操作的线性表。
顺序栈的存储构造是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置,base为栈底指针,在顺序栈中,它始终指向栈底,即top=base可作为栈空的标记,每当插入新的栈顶元素时,指针top增1,删除栈顶元素时,指针top减1。
2.2 算法设计为了实现算符优先算法。
可以使用两个工作栈。
一个称为OPTR,用以存放运算符,另一个称做OPND,用以存放操作数或运算结果。
1.首先置操作数栈为空栈,表达式起始符〞#〞为运算符栈的栈底元素;2.依次读入表达式,假设是操作符即进OPND栈,假设是运算符那么和OPTR栈的栈顶运算符比拟优先权后作相应的操作,直至整个表达式求值完毕〔即OPTR栈的栈顶元素和当前读入的字符均为〞. .word.zl.数据构造课程设计第 2 页#〞〕。
数据结构课程设计四则运算表达式求值(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 }。
表达式求值(数据结构)
结束算法,此时在OPND栈的栈顶得到 运算结果。
① 若ch是操作数,进OPND栈,从中缀表达式 取下一字符送入ch; ② 若ch是操作符,比较栈外icp(ch)的优先级和 栈内isp(OPTR)的优先级: 若icp(ch) > isp(OPTR),则ch进OPTR栈, 从中缀表达式取下一字符送入ch; 若icp(ch) < isp(OPTR),则从OPND栈退出 a2 和 a1 , 从 OPTR 栈 退 出 θ, 形 成 运 算 指 令 (a1)θ(a2),结果进OPND栈; 若icp(ch) == isp(OPTR) 且ch == “)”,则从 OPTR栈退出栈顶的“(”,对消括号,然后从 中缀表达式取下一字符送入ch;
优先级 操作符
1
单目-、!
2
*、/、%
3
+、-
4 <、<=、>、>=
5
==、!=
6
&&
7
||
一般表达式的操作符有4种类型:
1 算术操作符 如双目操作符(+、-、 *、/ 和%)以及单目操作符(-);
2 关系操作符 包括<、<=、==、!=、 >=、>。这些操作符主要用于比较;
3 逻辑操作符 如与(&&)、或(||)、非 (!);
38
icp (栈外) 0 8 6 4
21
isp叫做栈内(in stack priority)优先数。
icp叫做栈外(in coming priority)优先数。
操作符优先数相等的情况只出现在括号 配对或栈底的“;”号与输入流最后的“;” 号配对时。
C语言表达式求值
C语言表达式求值
c语言有丰富的表达式,这是它的特点之一,表达式主要有4类,算术表达式,赋值表达式,逗号表达式,关系表达式1.算术表达式就是包含算术运算符(如+-/*%等)的表达式(不是语句,后面没有分号),如:a+b,a%b,a+b-c*d,3+5等,算术表达式的值就是最后算出的结果,如3+5这个表达式的值就是82.赋值表达式,就是含有赋值运算符=的表达式,如a=5,b=3,c='A'等,=左边的a,b,c称为左值,必须为变量,=右边的5,3,'A'称为右值,必须为常量,赋值表达式的值为右值,如a=3的值为3,c='A'的值为字母A的ascii码65(当然也可以认为它的值就是字母A)3.逗号表达式就是含有逗号的表达式,形式:表达式1,表达式2,表达式3.......如a,b,c3,5,7a=3,b=4,c=63,a=5,b=6等逗号表达式的值为,最右边的表达式的值,如3,4,5的值就是5,表达式
a=3,b=4,c=6的值就是表达式b=6的值,
由上述分析知,表达式b=6的值就是6,所以表达式
a=3,b=4,c=6的值就是64.关系表达式,指含有关系运算符
(如><>====<等)的表达式(其实也是算术表达式的一种)如
a>b,a>6,6>5,3<2,4==6等,如果表达式的关系是正确的,那么表达式的值为1,否则为0如6>5正确,表达式的值为1,3<2,和4==6错误,表达式的值为0当然可以细分为很多种表达式,不过主要也就是这几种的变型。
数据结构表达式求值c语言
数据结构表达式求值c语言在C语言中,表达式通常由运算符和操作数组成。
运算符可以是算术运算符(如加减乘除)、关系运算符(如等于、不等于)或逻辑运算符(如与、或)。
操作数可以是变量、常量或其他表达式。
为了对表达式进行求值,我们需要将表达式转换为一种方便计算的形式。
常用的表达式形式有中缀表达式、后缀表达式和前缀表达式。
其中,后缀表达式也被称为逆波兰表达式,前缀表达式也被称为波兰表达式。
在表达式求值的过程中,我们可以使用栈这种数据结构来辅助计算。
栈是一种后进先出(Last In First Out,LIFO)的数据结构,可以用来保存运算符和中间结果。
我们可以通过以下步骤来求解一个后缀表达式:1. 创建一个空栈,用于保存操作数和中间结果。
2. 从左到右扫描后缀表达式的每个字符。
3. 如果遇到操作数,则将其压入栈中。
4. 如果遇到运算符,则从栈中弹出两个操作数,并根据运算符进行计算。
将计算结果压入栈中。
5. 重复步骤3和步骤4,直到扫描完所有字符。
6. 栈中最后剩下的元素即为表达式的求值结果。
下面是一个示例,演示如何使用后缀表达式求解一个简单的数学表达式:后缀表达式:"2 3 + 4 *"1. 创建一个空栈。
2. 从左到右扫描后缀表达式的每个字符。
- 遇到数字2,将其压入栈中。
- 遇到数字3,将其压入栈中。
- 遇到运算符+,从栈中弹出两个操作数2和3,计算2 + 3 = 5,并将结果5压入栈中。
- 遇到数字4,将其压入栈中。
- 遇到运算符*,从栈中弹出两个操作数5和4,计算5 * 4 = 20,并将结果20压入栈中。
3. 扫描完所有字符后,栈中最后剩下的元素20即为表达式的求值结果。
除了后缀表达式,我们还可以使用其他形式的表达式来进行求值。
前缀表达式的求值过程与后缀表达式类似,只是扫描的顺序从左到右变成了从右到左。
中缀表达式的求值过程比较复杂,需要使用算符优先级和括号来确定运算顺序。
在实际编程中,我们可以使用数组、链表或树等数据结构来表示和存储表达式。
C语言简单计算器原理——表达式求值(采用逆波兰表达式和栈结合)
C语⾔简单计算器原理——表达式求值(采⽤逆波兰表达式和栈
结合)
表达式的求解的关键是将其转换成逆波兰表达式(即后缀表达式,如1+2*3它的逆波兰表达式为123*+),在后缀表达式中已经考虑了运算符的优先级,
没有括号,只有操作数和运算符。
算术表达式转换成后缀表达式⽅法如下:
依次从键盘输⼊表达式的字符ch,对于每个ch:
(1)若ch为数字则直接将其放⼊后缀数组exp中并以#号标记数值串结束。
(2)若ch为"(",则直接将其压⼊字符栈op中。
(3)若ch为")",则将栈中"("以前的字符依次全部删除并将其放⼊后缀数组exp中,然后再将字符ch放⼊字符栈op中。
(4)若ch为"+"."-",则将栈中"("以前的运算符依次全部删除并将其放⼊后缀数组exp中,然后再将ch放⼊op栈中。
(5)若ch为"*"."/",则将栈顶连续的"*"."/"删除,并放⼊后缀数组exp中,然后将ch放⼊op栈中。
(6)若字符串str扫描完毕,则将栈中所有运算符删除并放⼊后缀数组exp,最后在后缀数组exp中便可得到后缀表达式。
在对后缀表达式求值时要⽤到⼀个数值栈st,在后缀数组exp中从头开始扫描,若是数字则将其放⼊数值栈中,
若遇到字符就进⾏两次退栈,并将运算结果再放⼊栈中,如此重复下去,最后当后缀数组扫描完后数值栈st的栈顶元素便是所要求的表达式的值。
数据结构之算术表达式求值C语言编写
#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAXLEN 100typedef struct{char ch;int level;}opt;typedef struct //定义操作栈{opt st[MAXLEN];int top;}Tstack;typedef struct //定义数据栈{double D[MAXLEN];int top;}Nstack;void Unit(Tstack *s) //初始化操作栈{s->top=-1;}//Unitvoid DUnit(Nstack *s) //初始化数据栈{s->top=-1;}//DUnitchar Push(Tstack *s,opt c) //入操作栈{s->top++;s->st[s->top]=c;return c.ch;}//Pushdouble DPush(Nstack *s,double c) //入数据栈{s->top++;s->D[s->top]=c;return c;}//DPushopt Top(Tstack *s) //操作栈栈顶{opt error={'$',-2};if(s->top>=0)return s->st[s->top];elsereturn error;}//Topdouble DTop(Nstack *s) //数据栈栈顶{if(s->top>=0)return s->D[s->top];elsereturn 0;}//DTopopt Pop(Tstack *s) //出操作栈{opt i;opt error={'$',-2};if(s->top>=0){i=s->st[s->top];s->st[s->top].ch='\0';s->top--;return i;}elsereturn error;}//Popdouble DPop(Nstack *s) //出数据栈{double i;if(s->top>=0){i=s->D[s->top];s->D[s->top]='\0';s->top--;return i;}else return 0;}//DPopint Empty(Tstack *s) //判断操作栈空{if(s->top<0)return 0;elsereturn s->st[s->top].ch;}//Emptyint NEmpty(Nstack *s) //判断数据栈空{if(s->top<0)return 0;elsereturn (int)(s->D[s->top]);}//NEmptydouble valuate(char *e) //计算{Tstack T;Nstack N;char tmp[MAXLEN]={'\0'};int i=0,leng;double d,dp;opt A={'+',1};opt R={'-',1};opt M={'*',2};opt D={'/',2};opt B={'(',-1};Unit(&T);DUnit(&N);while(*e!='\0'){while(*e >= '0' && *e <= '9' || *e == '.'){while(*e >= '0' && *e <= '9' || *e == '.'){tmp[i++]=*e++;}d=atof(tmp);DPush(&N,d);leng=strlen(tmp);for(i=0;i<leng;i++){tmp[i]='\0';}i=0;}switch(*e){case '+' :if(!Empty(&T) || Top(&T).level < A.level) {Push(&T,A);*e++;}else{while(Empty(&T) && Top(&T).level>=A.level) {switch(Pop(&T).ch){case '*' :dp=DPop(&N)*DPop(&N);DPush(&N,dp);break;case '/' :dp=DPop(&N);dp=DPop(&N)/dp;DPush(&N,dp);break;case '+':dp=DPop(&N)+DPop(&N);DPush(&N,dp);break;case '-':dp=DPop(&N);dp=DPop(&N)-dp;DPush(&N,dp);break;}}Push(&T,A);*e++;}break;case '-':if(!Empty(&T) || Top(&T).level < R.level) {Push(&T,R);*e++;}else{while(Empty(&T) && Top(&T).level>=R.level) {switch(Pop(&T).ch){case '*' :dp=DPop(&N)*DPop(&N);break;case '/' :dp=DPop(&N);dp=DPop(&N)/dp;DPush(&N,dp);break;case '+':dp=DPop(&N)+DPop(&N);DPush(&N,dp);break;case '-':dp=DPop(&N);dp=DPop(&N)-dp;DPush(&N,dp);break;}}Push(&T,R);*e++;}break;case '*':if(!Empty(&T) || Top(&T).level < M.level) {Push(&T,M);*e++;}else{while(Empty(&T) && Top(&T).level>=M.level) {switch(Pop(&T).ch){case '*' :dp=DPop(&N)*DPop(&N);DPush(&N,dp);break;case '/' :dp=DPop(&N);dp=DPop(&N)/dp;break;}}Push(&T,M);*e++;}break;case '/':if(!Empty(&T) ||Top(&T).level < D.level){Push(&T,D);*e++;}else{while(Empty(&T) &&Top(&T).level>=D.level) {switch(Pop(&T).ch){case '*' :dp=DPop(&N)*DPop(&N);DPush(&N,dp);break;case '/' :dp=DPop(&N);dp=DPop(&N)/dp;DPush(&N,dp);break;}}Push(&T,D);*e++;}break;case '(':Push(&T,B);e++;break;case ')':while(Top(&T).level!=-2){switch(Pop(&T).ch){case '*' :dp=DPop(&N)*DPop(&N);DPush(&N,dp);break;case '/' :dp=DPop(&N);dp=DPop(&N)/dp;DPush(&N,dp);break;case '+':dp=DPop(&N)+DPop(&N);DPush(&N,dp);break;case '-':dp=DPop(&N);dp=DPop(&N)-dp;DPush(&N,dp);break;}}Pop(&T);e++;break;}}while(Empty(&T)){switch(Pop(&T).ch){case '*' :dp=DPop(&N)*DPop(&N);DPush(&N,dp);break;case '/' :dp=DPop(&N);dp=DPop(&N)/dp;DPush(&N,dp);break;case '+':dp=DPop(&N)+DPop(&N);DPush(&N,dp);break;case '-':dp=DPop(&N);dp=DPop(&N)-dp;DPush(&N,dp);break;}}return DPop(&N);}//valuatevoid main(){char string[MAXLEN];char *p=string;printf("输入表达式:\n");gets(p);printf("%s=%f\n\n",string,valuate(p)); }。
数据结构实验二——算术表达式求值实验报告
数据结构实验二——算术表达式求值实验报告算术表达式求值实验报告一、引言算术表达式求值是计算机科学中一个重要的基础问题,它涉及到了数据结构和算法的应用。
本实验旨在通过实现一个算术表达式求值的程序,加深对数据结构中栈的理解和应用,并掌握算术表达式的求值过程。
二、实验目的1. 理解算术表达式的基本概念和求值过程;2. 掌握栈的基本操作和应用;3. 实现一个能够正确求解算术表达式的程序;4. 进一步熟悉编程语言的使用。
三、实验内容1. 设计并实现一个栈的数据结构;2. 实现算术表达式求值的算法;3. 编写测试用例,验证程序的正确性;4. 进行性能测试,分析算法的时间复杂度。
四、实验方法与步骤1. 设计栈的数据结构在本实验中,我们选择使用数组来实现栈的数据结构。
栈的基本操作包括入栈(push)、出栈(pop)、判断栈空(isEmpty)和获取栈顶元素(top)等。
2. 算术表达式求值算法算术表达式求值的一种常用算法是通过后缀表达式进行求值。
具体步骤如下: - 将中缀表达式转换为后缀表达式;- 通过栈来求解后缀表达式;- 返回最终的计算结果。
3. 编写测试用例编写一系列测试用例,包括不同类型的算术表达式,以验证程序的正确性。
例如:- 简单的四则运算表达式:2 + 3 * 4 - 5;- 包含括号的表达式:(2 + 3) * (4 - 5);- 包含多位数的表达式:12 + 34 * 56;- 包含浮点数的表达式:3.14 + 2.71828。
4. 性能测试和时间复杂度分析针对不同规模的输入数据,进行性能测试,记录程序的运行时间。
同时,分析算法的时间复杂度,验证算法的效率。
五、实验结果与分析我们设计并实现了一个栈的数据结构,并成功地完成了算术表达式求值的程序。
通过对一系列测试用例的验证,我们发现程序能够正确地求解各种类型的算术表达式,并返回正确的计算结果。
在性能测试中,我们对不同规模的输入数据进行了测试,并记录了程序的运行时间。
算术表达式求值(C )数据结构实验
数据结构实验报告实验名称:实验2栈和队列及其应用实验目的:通过上机实验,加深理解栈和队列的特性;能根据实际问题的需要灵活运用栈和队列;掌握栈和队列的应用。
实验内容:(2选1)内容1:算术表达式求值问题;内容2:航空客运订票系统。
实验要求:1)在C++系统中编程实现;2)至少实现两种以上操作算法;3)写出算法设计的基本原理或画出流程图;4)算法实现代码简洁明了;关键语句要有注释;5)给出调试和测试结果;6)完成实验报告。
实验步骤:(1)算法设计为了实现算符优先算法。
可以使用两个工作栈。
一个称为OPTR,用以寄存运算符,另一个称做OPND,用以寄存操作数或运算结果。
1.首先置操作数栈为空栈,表达式起始符”#”为运算符栈的栈底元素;2.依次读入表达式,若是操作符即进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为”#”)。
(2)算法实现typedef struct{int stacksize;char*base;char*top;}Stack;typedef struct{int stacksize;int*base;int*top;}Stack2;int InitStack(Stack*s)//构造运算符栈{s->base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));if(!s->base)return ERROR;s->top=s->base;s->stacksize=STACK_INIT_SIZE;return OK;}int InitStack2(Stack2*s)//构造操作数栈{s->base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));if(!s->base)return ERROR;s->stacksize=STACK_INIT_SIZE;s->top=s->base;return OK;}int In(char ch)//判断字符是否是运算符,运算符即返回1 {return(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='#');}int Push(Stack*s,char ch)//运算符栈插入ch为新的栈顶元素{*s->top=ch;s->top++;return0;}int Push2(Stack2*s,int ch)//操作数栈插入ch为新的栈顶元素{*s->top=ch;s->top++;return0;}char Pop(Stack*s)//删除运算符栈s的栈顶元素,用p返回其值{char p;s->top--;p=*s->top;return p;}int Pop2(Stack2*s)//删除操作数栈s的栈顶元素,用p返回其值{int p;s->top--;p=*s->top;return p;}char GetTop(Stack s)//用p返回运算符栈s的栈顶元素{char p=*(s.top-1);return p;}int GetTop2(Stack2s)//用p返回操作数栈s的栈顶元素{int p=*(s.top-1);return p;}char Precede(char c1,char c2){int i=0,j=0;static char array[49]={'>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>','<','<','<','<','<','=','!','>','>','>','>','!','>','>','<','<','<','<','<','!','='};switch(c1){case'+':i=0;break;case'-':i=1;break;case'*':i=2;break;case'/':i=3;break;case'(':i=4;break;case')':i=5;break;case'#':i=6;break;}switch(c2){case'+':j=0;break;case'-':j=1;break;case'*':j=2;break;case'/':j=3;break;case'(':j=4;break;case')':j=5;break;case'#':j=6;break;}return(array[7*i+j]);}int Operate(int a,char op,int b){switch(op){case'+':return(a+b);case'-':return(a-b);case'*':return(a*b);case'/':return(a/b);}return0;}int num(int n)//返回操作数的长度{char p[10];itoa(n,p,10);//把整型转换成字符串型n=strlen(p);return n;}int EvalExpr(){char c,theta,x;int n,m;int a,b;c=*ptr++;while(c!='#'||GetTop(OPTR)!='#'){if(!In(c)){if(!In(*(ptr-1)))ptr=ptr-1;m=atoi(ptr);//取字符串前面的数字段n=num(m);Push2(&OPND,m);ptr=ptr+n;c=*ptr++;}else{switch(Precede(GetTop(OPTR),c)){case'<':Push(&OPTR,c);c=*ptr++;break;case'=':x=Pop(&OPTR);c=*ptr++;break;case'>':theta=Pop(&OPTR);b=Pop2(&OPND);a=Pop2(&OPND); Push2(&OPND,Operate(a,theta,b));break;}}return GetTop2(OPND);}实验结果:。
数据结构实验报告-3-求解算术表达式
实验3 利用栈实现算术表达式求值一、实验目的1、帮助读者复习C语言程序设计中的知识。
2、熟悉栈的逻辑结构。
3、了解算术表达式计算的逻辑过程。
4、熟悉算术表达式计算过程中优先级的运算方法。
5、了解中缀表达式和后缀表达式的区别。
二、实验内容[问题描述]1.实验目标:利用栈的特性,实现算术表达式的运算,了解算术运算的逻辑,掌握栈的特性。
2.中缀表达式与后缀表达式的含义中缀表达式就是通常所说的算术表达式,比如(1+2)*3-4。
后缀表达式是指通过解析后,运算符在运算数之后的表达式,比如上式解析成后缀表达式就是12+3*4-。
这种表达式可以直接利用栈来求解。
[基本要求](1)利用栈实现后缀表达式的计算;(2)利用栈实现中缀表达式到后缀表达式的转换。
(可选)基于程序易于设计的考虑,我们仅需要实现一位数值(0-9)的+,-,*,/,()等运算。
三、设计思路四、源代码#include<stdio.h>#include<string.h>#include<stdlib.h>#define max 100typedef struct{float data[max];int top;}seqstack;void InitStack(seqstack *s);int StackEmpty(seqstack *s);int StackFull(seqstack *s);void Push(seqstack *s,char x);int Pop(seqstack *s);float ComputeExpress(char a[]);void main(){char a[max],b[max];float f;printf("请输入一个后缀表达式:\n");gets(a);printf("后缀表达式为:%s\n",a);f=ComputeExpress(b);printf("计算结果为:%f\n",f);}void InitStack(seqstack *s){s->top=-1;}int StackEmpty(seqstack *s){return s->top==-1;}int StackFull(seqstack *s){return s->top==max-1;}void Push(seqstack *s,char x){if(StackFull(s))printf("overflow");s->data[++s->top]=x;}int Pop(seqstack *s){if(StackEmpty(s))printf("underflow");return s->data[s->top--];}float ComputeExpress(char a[]){seqstack s;int i=0;float x1,x2,value;float result;s.top=-1;while(a[i]!='\0'){if(a[i]!=' '&&a[i]>='0'&&a[i]<='9'){value=0;while(a[i]!=' '){value=10*value+a[i]-'0';i++;}s.top++;s.data[s.top]=value;}else{switch(a[i]){case'+':x1=s.data[s.top];s.top--;x2=s.data[s.top];s.top--;result=x1+x2;s.top++;s.data[s.top]=result;break;case'-':x1=s.data[s.top];s.top--;x2=s.data[s.top];s.top--;result=x2-x1;s.top++;s.data[s.top]=result;break;case'*':x1=s.data[s.top];s.top--;x2=s.data[s.top];s.top--;result=x1*x2;s.top++;s.data[s.top]=result;break;case'/':x1=s.data[s.top];s.top--;x2=s.data[s.top];s.top--;result=x2/x1;s.top++;s.data[s.top]=result;break;}i++;}}if(s.top!=-1)result=s.data[s.top];s.top--;if(s.top==-1)return result;else{printf("表达式错误");exit(-1);}}五、测试结果六、心得体会这次实验我只做了利用栈实现后缀表达式的计算熟悉栈的逻辑结构,同时了解算术表达式计算的逻辑过程。
C语言_算术表达式求值_代码
C语言_算术表达式求值_代码源代码://用来存储字符的结点类型typedef struct CharNode{char c;struct CharNode *next;}CharNode;//用来存储数的结点类型typedef struct IntNode{long double i;struct IntNode *next;}IntNode;//用来存储数的结点类型typedef struct Node{long double n;struct Node_ys_char *next;}Node;//用来存储运算符的结点类型typedef struct Node_ys_char{char c;struct Node_ys_char *next_c;struct Node *next;}Node_ys_char;char Precede(char x,char y)//运算符优先级判断{ int i,j;int from[5][5]={{0,0,-1,-1,0},{0,0,-1,-1,0},{1,1,0,0,1},{1,1,0,0,1},{0,0,-1,-1,0}};//定义一个二维数组存放算术符号的优先级switch(x){case '+':i=0;break;case '-':i=1;break;case '*':i=2;break;case '/':i=3;break;case '#':i=4;break;}switch(y){case '+':j=0;break;case '-':j=1;break;case '*':j=2;break;case '/':j=3;break;case '#':j=4;break;}if(from[i][j]==1)//说明运算符i的优先级比j的优先级高return '>';if(from[i][j]==-1)return '<';elsereturn '=';}//输入表达式,并对特殊情况做处理CharNode *CreatRegister(){CharNode *top,*p,*q,*e;top=(CharNode *)malloc(sizeof(CharNode)); p=q=top;scanf("%c",&p->c);scanf("%c",&p->c);if(q->c=='-'){p=(CharNode *)malloc(sizeof(CharNode)); p->c='0';p->next=q;top=p;p=q;}if(q->c=='('){e=(CharNode *)malloc(sizeof(CharNode)); e->c='0';p=(CharNode *)malloc(sizeof(CharNode)); p->c='+';e->next=p;p->next=q;p=q;top=e;}while(p->c!='#'){q=(CharNode *)malloc(sizeof(CharNode)); scanf("%c",&q->c);if((p->c=='(')&&(q->c=='-')){e=(CharNode *)malloc(sizeof(CharNode));e->c='0';e->next=q;p->next=e;p=q;}else{p->next=q;p=q;}}p->c='+';p->next=(CharNode *)malloc(sizeof(CharNode)); p->next->c='0';p=p->next;p->next=(CharNode *)malloc(sizeof(CharNode)); p->next->c='#';return top;}//将数与运算符分开,并将其他进制转化为10进制Node *StackChange(CharNode *top,int m){CharNode *p,*q;long double x=0,y=0;char a[10],b[10];int n=0,i=0,JiWei,max,min=47,mark_1=0,mark_2=0,h,k=0; Node *node,*head;Node_ys_char *node_char;switch(m){case 2:JiWei=2;max=50;break;case 8:JiWei=8;max=56;break;case 10:JiWei=10;max=97;break;case 16:JiWei=16;max=103;break;}p=q=top;while(p->c !='#'){while((q->c>min)&&(q->cc==46)) {if(q->c==46){mark_1=1;q=q->next;}if(mark_1==0){a[n]=q->c;q=q->next;n++;}if(mark_1==1){b[i]=q->c;q=q->next;i++;}}for(h=n-1;h>=0;h--){x=(a[n-h-1]-48)*pow(JiWei,h)+x;// }for(h=0;h<i;h++)< p="">{y=y+(b[h]-48)*pow(JiWei,(-(h+1)));//}node=(Node *)malloc(sizeof(Node));//node->n=x+y;mark_1=0;n=0;i=0;if(mark_2==1)node_char->next=node;node_char=(Node_ys_char *)malloc(sizeof(Node_ys_char)); node_char->c=q->c;node->next=node_char;node_char->next_c=NULL;node_char->next=NULL;if(q->c=='#'){node->next=(Node_ys_char *)malloc(sizeof(Node_ys_char));node->next->c='#';return head;}q=q->next;if(q->c<=min)while(q->c<=min){node_char->next_c=(Node_ys_char*)malloc(sizeof(Node_ys_char));node_char->next_c->c=q->c;q=q->next ;//node->next=node_char;node_char=node_char->next_c;node_char->next_c=NULL;node_char->next=NULL;}else{node->next=node_char;node_char->next_c=NULL;node_char->next=NULL;}p=q;n=0;x=0;y=0;if(mark_2==0){head=node;mark_2=1;}}return head;}//作只有加减乘除运算的表达式求值Node *Compute(Node *p){int mark=0;Node *m,*n;char max_char,min_char;m=n=p;while(p->next->c!='#'){max_char=n->next->c;n=n->next->next;min_char=n->next->c;if((Precede(max_char,min_char)=='<'||Precede(max_char,min _char)=='=')&&mark!=1) {m=n;}if(Precede(max_char,min_char)=='>'||mark==1){switch(m->next->c){case '+':m->n =m->n + n->n ;break;case '-':m->n =m->n - n->n ;break;case '*':m->n =m->n * n->n ;break;case '/':m->n =m->n / n->n ;break;}m->next=n->next;n=m;}if(m->next->c=='#'){m=n=p;mark=1;}}return m;}//求用户输入表达式的值Node *GetOutcome(Node *head){Node *p,*q,*R;Node_ys_char *m,*n,*t,*k;n=(Node_ys_char *)malloc(sizeof(Node_ys_char)); n->c='(';p=q=head;while((n->c!=')')&&(q->next->c!='#')){if(q->next->c=='('){m=q->next;k=m;}else if(q->next->next_c==NULL) q=q->next->next;else{m=q->next->next_c;k=q->next;// t=q->next;if(m->c=='('){t=k;k=m;}while(m->next_c!=NULL){m=m->next_c;if(m->c=='('){t=k;k=m;}}q=m->next ;}if(q->next->c==')'){n=q->next;}}if(n->c==')'){p=k->next;q->next->c='#';R=Compute(p);t->next =R;t->next_c=NULL;R->next=n->next_c;GetOutcome(head);}else{R=Compute(head);return R;}}main(){int m;//进制char a;CharNode *top_1;Node *top_2,*R;printf("\n\n");printf("███████████████████████████████████████\n");printf("████\n");printf("██表达式求值系统██\n");printf("████\n");printf("███████████████████████████████████████\n");printf("本程序可分别进行2进制,8进制,10进制,16进制的加减乘除运算:\n");loop:printf("...............请输入进制..............\n");printf("你选的进制为:");scanf("%d",&m);printf("请输入表达式,表达式请以#结尾:\n");top_1=CreatRegister();//录入表达式,并对特殊情况作处理,将头指针带回;top_2=StackChange(top_1,m);//进制转换,将数与运算符分开,将头指针带回;R=GetOutcome(top_2);得出结果printf("运算结果的十进制形式为:\n");printf("%lf",R->n);printf("\n继续进行运算请输入y否则退出:\n");scanf("%c",&a);scanf("%c",&a);if(a=='y'||a=='Y')goto loop;}</i;h++)<>。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
optrElem GetTop_OPTR(OptrStack S); //若栈不为空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 FALSE Status Push_OPTR(OptrStack *S,optrElem e); //插入元素 e 为新的栈顶元素 Status Pop_OPTR(OptrStack *S,optrElem *e); //若栈 S 不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK,否则返回 ERROR //============运算操作================// void Standard(char *expression); //将表达式标准化 opndElem EvalueateExpression(const char *expression); //算数表达式求值 Status Isoperator(char c); //判断 c 是否是一个操作符 char Precede(char op1,char op2); //判断 op1 和 op2 优先级的高低,返回'>','<','=' opndElem operate(opndElem a,optrElem theta,opndElem b); //对操作数 a,b 进行 theta 运算 const char *getOpnd(const char *c,opndElem *op); //获得以*c 开始的操作数,返回后 c 为操作符 int main() { opndElem result=0; char *expression=(char*)malloc(sizeof(char)*BUFFERSIZE); if(expression==NULL){ printf("Sorry,memory initialize error.\n"); exit(0); } printf("Please input an expression:\n"); gets(expression); //printf("Before standard:%s\n",expression); Standard(expression);//标准化 //printf("Standard expression:%s\n",expression); result=EvalueateExpression(expression); printf("The result of the expression:%d\n",result); return 0; } //==========操作数栈===========// Status InitStack_OPND(OpndStack *S){ //构造一个空操作数栈 S S->base=(opndElem *)malloc(STACK_INIT_SIZE*sizeof(opndElem)); if(!S->base)//分配失败
//顺序栈的应用:表达式求值 //允许用户输入空格(系统自动删除) ,只能进行整数的四则运算,支持小括号 //对不能整除的将按两个整数除法规则进行取整 //作者:nuaazdh //时间:2011 年 12 月 8 日 10:49:39 #include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define BUFFERSIZE 256 typedef int Status; //函数返回状态 typedef int opndElem; //操作数元素类型 typedef struct{//操作数栈结构定义 opndElem *base; opndElem *top; int stacksize; }OpndStack; typedef char optrElem;//操作符元素类型 typedef struct{//操作符栈结构定义 optrElem *base; optrElem *top; int stacksize; }OptrStack; //==========操作数栈=============// Status InitStack_OPND(OpndStack *S); //构造一个空栈 S Status GetTop_OPND(OpndStack S,opndElem *e); //若栈不为空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 FALSE Status Push_OPND(OpndStack *S,opndElem e); //插入元素 e 为新的栈顶元素 Status Pop_OPND(OpndStack *S,opndElem *e); //若栈 S 不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK,否则返回 ERROR //==========操作符栈=============// Status InitStack_OPTR(OptrStack *S); //构造一个空栈 S
Pop_OPND(&OPND,&a); result=operate(a,theta,b); //printf("temp result is:%d\n",result); Push_OPND(&OPND,result); break; default: //printf("Precede:%c",Precede(GetTop_OPTR(OPTR),*c)); break; }//switch }//while GetTop_OPND(OPND,&result); return result; } void Standard(char *expression){ //将字符串表达式标准化为算术表达式 char *p=expression,*q; while(*p!='\0'){//遍历字符串 if(*p==' '){//如果是空格,删除 q=p; do{ *q=*(q+1); q++; }while(*q!='\0'); } p++; } *p++='#'; *p='\0'; } const char *getOpnd(const char *c,opndElem *op){ //获得以*c 开始的操作数,返回后 c 为操作符 int sum=0,tmp; while(FALSE==Isoperator(*c)){//当 c 不是操作符 tmp=*c-'0'; sum=sum*10+tmp; //printf("tmp=%d\n",tmp); c++; } *op=sum; //printf("getOpnd:%d\n",*op); return c; }
return OK; } //==========操作符栈===========// Status InitStack_OPTR(OptrStack *S){ //构造一个空操作数栈 S S->base=(optrElem *)malloc(STACK_INIT_SIZE*sizeof(optrElem)); if(!S->base)//分配失败 { printf("分配内存失败.\n"); exit(0); } S->top=S->base; S->stacksize=STACK_INIT_SIZE; return OK; } optrElem GetTop_OPTR(OptrStack S){ //若操作数栈不为空,则返回 S 的栈顶元素,并返回 OK;否则返回 FALSE optrElem e; if(S.top==S.base){ printf("栈为空.\n"); }else{ e=*(S.top-1); } return e; } Status Push_OPTR(OptrStack *S,optrElem e){ //插入元素 e 为新的栈顶元素 if(S->top-S->base>=S->stacksize){//栈已满,追加存储空间 S->base=(optrElem *)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(optrElem)); if(!S->base) { printf("重新申请空间失败.\n"); exit(0); } S->top=S->base+S->stacksize;//更改栈顶指针 S->stacksize+=STACKINCREMENT; } *S->top++=e; return OK; }
{ printf("分配内存失败.\n"); exit(0); } S->top=S->base; S->stacksize=STACK_INIT_SIZE; return OK; } Status GetTop_OPND(OpndStack S,opndElem *e){ //若操作数栈不为空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 FALSE if(S.top==S.base){ printf("栈为空.\n"); return FALSE; }else{ *e=*(S.top-1); return OK; } } Status Push_OPND(OpndStack *S,opndElem e){ //插入元素 e 为新的栈顶元素 if(S->top-S->base>=S->stacksize){//栈已满,追加存储空间 S->base=(opndElem *)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(opndElem)); if(!S->base) { printf("重新申请空间失败.\nbase+S->stacksize;//更改栈顶指针 S->stacksize+=STACKINCREMENT; } *S->top++=e; return OK; } Status Pop_OPND(OpndStack *S,opndElem *e){ //若栈 S 不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK,否则返回 ERROR if(S->top==S->base){//栈为空 printf("栈为空.\n"); return ERROR; } *e=*(--S->top);