数据结构C语言表达式求值(带详细注释)

合集下载

数据结构-算术表达式求值(含需求分析和源代码)

数据结构-算术表达式求值(含需求分析和源代码)

需求分析(附代码)一、需求分析(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语言支持的算术运算符包括加法(+)、减法(-)、乘法(*)、除法(/)和求余(%)等。

这些运算符用于对数值进行基本的加减乘除运算。

在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语言中的算术表达式求值是按照运算符优先级和运算次序进行的,遵循从左到右的计算规则。

数据结构实验报告 表达式求值

数据结构实验报告 表达式求值

(一) 需求分析1、输入的形式和输入值的范围:根据题目要求与提示,先选择你要使用的表达式形式(中缀用1,后缀用0),在输入一个中缀表达式,输入数的范围为int型,此时,程序将计算出表达式的结果。

2、输出的形式:当按照程序要求选择了1或0之后,再输入表达式;如果选择的是1,则程序将自动运算出表达式结果;如果之前选择的是0,则程序将现将中缀表达式转化为后缀表达式并计算出结果。

3、程序所能达到的功能:本程序能计算出含+、-、*、/、(、)等运算符的简单运算。

4、测试数据:输入一个表达式,如果你之前选择的是“中缀表达式”,那么输入5*(4-2)#,那么输出结果是10;如果之前选择的是“后缀表达式”,那么输入5*(4-2)#,那么他将先转换成后缀表达式5 4 2 - * #,再输出结果10。

如果输入表达式没有结束标示符#,如5*(4-2),那将不会输出任何结果,或出现错误结果。

(二) 概要设计为了实现上述操作,应以栈为存储结构。

1.基本操作:(1). int GetTop(SqStack *s)初始条件:栈存在;操作结果:若栈为空,则返回s的栈顶元素;否则返回ERROR。

(2).void Push(SqStack *s,int e)初始条件:栈存在;操作结果:插入e为新的栈顶元素。

(3).int Pop(SqStack *s)初始条件:栈存在;操作结果:若栈不空,则删除之,并返回其值;否则返回REEOR。

(4).void InitStack(SqStack *s)初始条件:栈存在;操作结果:置栈为空。

(5).int Empty(SqStack *s)初始条件:栈存在;操作结果:判定s是否为空栈。

(6).int Operate(int a,char theta, int b)初始条件:操作数a和b存在,且theta是+、-、*、/四则运算;操作结果:返回a与b间theta运算的结果。

(7).int In(char s,char* TestOp)初始条件:s为待判断字符,TestOp为已知的算符集合;操作结果:s为算符集合中的元素则返回1,否则返回0.(8).int ReturnOpOrd(char op,char* TestOp)初始条件:op为待确定运算符,TestOp为已知的算符集合;操作结果:确定运算符类型。

c语言算术表达式求值

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 语言算术表达式的求值方法有了更加深入的了解。

数据结构表达式求值完整篇(含实验报告)

数据结构表达式求值完整篇(含实验报告)
char ch;
的是p*low),继续输入ch
总结:
我觉得写的好的地方在于定义了flag,low分别作为小数入栈和负号与减号区别的条
件。第一次写这么长的代码,还有就是将输入的字符再转到小数这段代码可以留着很有 用。开始考虑的大整数想麻烦了,直接用double难度降低了很多
4
【列岀你的测试结果,包括输入和岀。测试数据应该完整和严格,最好多于需求分析中所列。】
if(!s.base)
printf("\n运算符栈存储分配失败!\n");
s.top=s.base;
s.stacksize=MAXSIZE;
}
//
void OPND」n itStack(Sqstack_OPND &s)
{
s.base=new SElemType_OPND[MAXSIZE];
if(!s.base)
操作数和运算符分别入不同的栈charint进操作数栈先考虑了小于10的整数直接进栈重点是运算符的优先级这块函数的编写前面的都听简单的就是小数编写这块想了很久定义了low做判定符号的标志
数据结构表达式求值完整篇(含 实验报告)
1
(1)深入理解栈的特点及其描述方法
(2)能够在两种存储结构上实现栈抽象数据类型实现
&s,SElemType_OPND&e); //出栈
/*
#i nclude "common .h"
#include "Sqstack.h"
#in clude "other.h"
//
void OPTR_I ni tStack(Sqstack_OPTR &s)
{

数据结构表达式求值(中缀)实验报告

数据结构表达式求值(中缀)实验报告

数据结构表达式求值(中缀)实验报告题目名称表达式求值学号姓名指导教师日期一1. 问题描述:在计算机中,算术表达式由常量、变量、运算符和括号组成。

由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。

2. 表达式求值这个程序,主要利用栈和数组,把运算的先后步骤进行分析并实现简单的运算,以字符列的形式从终端输入语法的正确的、不含变量的整数表达式。

利用已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。

该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。

1、基本思想(中缀表达式求值)要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式,要了解算术四则运算的规则即:(1)先乘除后加减;(2)从左到右计算;(3)先括号内,后括号外。

下表定义的运算符之间的关系:b + - * / () # a+ > > < < < > > _ > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # < < < < < =为了实现运算符有限算法,在程序中使用了两个工作栈。

分别是:运算符栈OPTR,操作数栈OPND.基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈得栈顶运算符比较优先级后作相应操作。

表达式求值c语言程序

表达式求值c语言程序

表达式求值c语言程序#include <stdio.h>#include <stdlib.h>#include <ctype.h>char expression[100];int pos = 0;int num1, num2;char op;int parse_expr() {int i;num1 = parse_term();while (expression[pos] != '\0') {op = expression[pos];pos++;num2 = parse_term();switch (op) {case '+':num1 += num2;break;case '-':num1 -= num2;break;case '*':num1 *= num2;break;case '/':num1 /= num2;break;default:printf("Invalid operator: %c\n", op); exit(1);}}return num1;}int parse_term() {int i, n = 0;while (isdigit(expression[pos])) {n = n * 10 + (expression[pos] - '0'); pos++;}return n;}int main() {printf("Enter an expression: ");fgets(expression, 100, stdin);pos = 0;printf("Result: %d\n", parse_expr());return 0;}该程序使用递归下降解析算法来解析表达式。

在解析表达式时,程序从左到右依次扫描表达式中的每个字符,并使用递归函数来解析每个子表达式和操作数。

数据结构课程设计四则运算表达式求值(C语言版)

数据结构课程设计四则运算表达式求值(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 }。

C语言表达式求值

C语言表达式求值

表达式求值,输入一个表达式,如1+2*3#,程序可计算出结果为7支持以下符号:+ - * / ( ) ^ .可以计算整数、小数其中^表示次方,2^5表示2的5次方*//*头文件*/#include <>#include <>#include <>#include <>#include <>/*宏定义*/#define INIT_STACK_SIZE 100#define SET_NUM 8#define N 100/*字符优先级表*/unsigned char prior[SET_NUM][SET_NUM] ={/* '+' '-' '*' '/' '(' ')' '#' '^' *//*'+'*/'>', '>', '<', '<', '<', '>', '>', '<',/*'-'*/'>', '>', '<', '<', '<', '>', '>', '<',/*'*'*/'>', '>', '>', '>', '<', '>', '>', '<',/*'/'*/'>', '>', '>', '>', '<', '>', '>', '<',/*'('*/'<', '<', '<', '<', '<', '=', ' ', '<',/*')'*/'>', '>', '>', '>', ' ', '>', '>', '>',/*'#'*/'<', '<', '<', '<', '<', ' ', '=', '<',/*'^'*/'>', '>', '>', '>', '<', '>', '>', '>'};unsigned char priorSet[SET_NUM] = {'+', '-', '*', '/', '(', ')', '#', '^'};/*结构体定义,这是用来存放字符的栈*/typedef struct{char *base;char *top;int stacksize;} SqStackC;/*结构体定义,这是用来存放数字的栈*/typedef struct{double *base;double *top;int stacksize;} SqStackN;void initStackN(SqStackN &);void initStackC(SqStackC &);void pushN(SqStackN &, double);void pushC(SqStackN &, double);void popN(SqStackN &, double &);void popC(SqStackN &, double &);double calculate(double, char, double);int findInSet(char);char compare(char, char);void getSolution();/*主函数*/void main(){getSolution();}/*初始化数字栈*/void initStackN(SqStackN &S){= (double*) malloc(INIT_STACK_SIZE * sizeof(double));= ;= INIT_STACK_SIZE;}/*初始化字符栈*/void initStackC(SqStackC &S){= (char*) malloc(INIT_STACK_SIZE * sizeof(char));= ;= INIT_STACK_SIZE;}/*向数字栈中存放数字*/void pushN(SqStackN &S, double x){if >=return;*++) = x;}/*向字符栈中存放字符*/void pushC(SqStackC &S, char x){if - >=return;*++) = x;}/*从数字栈中取出数字*/void popN(SqStackN &S, double &x){if ==return;x = *;}/*从字符栈中取出字符*/void popC(SqStackC &S, char &x){if ==return;x = *;}/*这个函数返回a operation b的值。

C语言表达式求值

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语言在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语言对字符串表达式求值小数运算

c语言对字符串表达式求值小数运算在C语言中,你可以使用标准库中的函数来对字符串表达式求值。

这通常涉及到一些库函数,如`strtod()` 用于将字符串转换为浮点数,以及`eval()` 函数(尽管在C标准库中没有`eval()`,但一些第三方库提供此功能)。

下面是一个简单的示例,演示如何使用`strtod()` 函数将字符串表达式转换为浮点数,并进行计算:```c#include <stdio.h>#include <stdlib.h>#include <string.h>int main() {char expression[] = "3.14 + 2.718 * 2";char *endptr;double result;double num1 = strtod(expression, &endptr);if (endptr == expression) {printf("无法解析数字\n");return 1;}while (*endptr == ' ') {endptr++;}if (*endptr == '\0') {printf("表达式为:%s,结果为:%f\n", expression, num1);return 0;}double num2 = strtod(endptr, &endptr);while (*endptr == ' ') {endptr++;}if (*endptr == '\0') {result = num1 + num2;} else {result = num1 * num2;}printf("表达式为:%s,结果为:%f\n", expression, result);return 0;}```这个示例程序将解析并计算字符串表达式"3.14 + 2.718 * 2"。

C语言简单计算器原理——表达式求值(采用逆波兰表达式和栈结合)

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的栈顶元素便是所要求的表达式的值。

数据结构课程设计之算术表达式求值

数据结构课程设计之算术表达式求值

1【实验题目及要求】[问题描述]一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。

假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。

引入表达式起始、结束符是为了方便。

编程利用“算符优先法”求算术表达式的值。

[基本要求](1)从键盘或文件读入一个合法的算术表达式,输出正确的结果。

(2)显示输入序列和栈的变化过程。

(3)考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。

(4) 实现非整数的处理(可选功能)。

2【源代码(C语言)】#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAXSIZE 20#define OK 1#define ERROR 0#define OVERLOW 0#define YES 1#define NO 0typedefstruct{char * base;char * top;int stacksize; //最大存储量}OPTR; //字符存储栈typedefstruct{float *base;float *top;int stacksize; //最大存储量}OPND; //数值存储栈int InitOptrStack(OPTR *); //字符栈初始化函数int OptrPush(OPTR *, char); //进字符栈操作int OptrPop(OPTR*, char *); //出字符栈操作int OptrEmpty(OPTR ); //判断字符栈是否为空char GetOptrTop(OPTR); //返回字符栈顶元素int InitOpndStack(OPND *); //数值栈初始化函数int OpndPush(OPND *, float); //进数值栈操作int OpndPop(OPND*, float*); //出数值栈操作int OpndEmpty(OPND ); //判断数值栈是否为空int JudgeChar(char); //判断是否为字符float GetFloat(char *); //接收一个数字char Precede(char, char); //判断优先级操作float Caculate(float,float,char);//计算数值{char ch, noMean, ci;float num, number1, number2;OPTR optr;OPND opnd;//system("color 30");InitOptrStack(&optr);InitOpndStack(&opnd);while(1){printf(" 请输入表达式以“#”开始,以“#”结束\n ");do{ch = getchar();}while(ch !='#'); //忽略前面非‘#’字符OptrPush(&optr, ch);ch = getchar();while(ch != '#' || GetOptrTop(optr) != '#'){if(!JudgeChar(ch)){ //如果输入的是数字num = GetFloat( &ch );OpndPush(&opnd, num);else{ //输入的是字符switch(Precede(GetOptrTop(optr),ch)){case'<':OptrPush(&optr,ch); //栈顶优先级低ch = getchar();break;case'=':OptrPop(&optr,&noMean); //左右括号,把左括号出栈ch = getchar ();break;case'>': //栈顶优先级高if(OpndPop(&opnd, &number2) && OpndPop(&opnd,&number1)){OptrPop(&optr, &ci);num = Caculate(number1, number2, ci ); //出栈计算OpndPush(&opnd, num);}else{printf(" 输入过多运算符!\n");system ("PAUSE");exit(0);}break;}//witch}//else}if(opnd.top -opnd.base >= 2){printf(" 俩个括号之间缺少运算符!\n ");system ("PAUSE");exit( 0 );}OpndPop(&opnd,&num); //直接把OPND的栈元素赋值给numprintf(" 运算结果为%.3f\n", num);}system ("PAUSE");}int InitOptrStack(OPTR * OP){OP->base = (char*)malloc((MAXSIZE+1)*sizeof(char));OP->top = OP->base;OP->stacksize = MAXSIZE;return OK;}int OptrPush(OPTR *OP, char ch){*(OP->top) = ch;OP->top++;return OK;}int OptrPop(OPTR *OP, char *ch){if(OP->base == OP->top)return ERROR;else{OP->top--;*ch = *(OP->top);return OK;}}int OptrEmpty(OPTR OP){if(OP.top == OP.base )return YES;elsereturn NO;}char GetOptrTop(OPTR OP){return *(OP.top -1);}int InitOpndStack(OPND * OP){if(!(OP->base = (float*)malloc((MAXSIZE+1)*sizeof(float)))) exit(OVERLOW);OP->top = OP->base;OP->stacksize = MAXSIZE;return OK;}int OpndPush(OPND *OP, float number) {*(OP->top) = number;OP->top++;return OK;}int OpndPop(OPND *OP, float* number) {if(OP->top == OP->base)return ERROR;else{OP->top--;*number = *(OP->top);return OK;}}int OpndEmpty(OPND OP){if(OP.top == OP.base )return YES;elsereturn NO;}int JudgeChar(char ch){if(ch>='0'&&ch<= '9')return NO;elsereturn YES;}float GetFloat(char* ch){int i;float num = 0;for( i = 0; *ch>= '0'&& *ch<= '9'; i++){ num = num*10 + *ch - '0';*ch = getchar();}return num;}char Precede(char a, char b){char ch;switch(a){case'+':case'-': if(b == '*' || b == '/' || b == '(')ch = '<';elsech = '>';break;case'*':case'/': if( b == '(')ch = '<';elsech = '>';break;case'(': if(b == ')')ch = '=';elseif(b == '#'){printf(" 缺少反括号\n");system ("PAUSE");exit(0);}elsech = '<';break;case')': if(b == '('){printf(" 两个括号之间没有符号相连!\n");system("PAUSE");exit(0);}ch = '>';break;case'#': if(b == '#')ch = '=';elseif(b == ')'){printf(" 没有左括号!\n ");system("PAUSE");exit(0);}elsech = '<';break;default: printf(" 输入运算符超出范围! \n ");system ("PAUSE");exit(0);break;}return ch;}float Caculate(float number1, float number2, char ci){float num;switch( ci){case'+': num = number1 + number2; break;case'-': num = number1 - number2; break;case'*': num = number1 * number2; break;case'/': num = number1 / number2; break;}return num;}3【算法思想】根据栈的原理,建立数字栈OPND和运算符号栈OPTR,对读入的字符进行判断,存入不同的栈内,每次读入一个字符就把该字符和运算符栈顶的优先级进行比较,然后选择相应的操作,这是这个程序的核心代码,如下:switch(Precede(GetOptrTop(optr),ch)){case '<':OptrPush(&optr,ch); //栈顶优先级低ch = getchar();break;case '=':OptrPop(&optr,&noMean); //左右括号,把左括号出栈ch = getchar ();break;case '>': //栈顶优先级高if(OpndPop(&opnd, &number2) && OpndPop(&opnd, &number1)){OptrPop(&optr, &ci);num = Caculate(number1, number2, ci ); //出栈计算OpndPush(&opnd, num);}else{printf(" 输入过多运算符!\n");system ("PAUSE");exit(0);}break;}//witch4【实现效果】完全可以实现题目的要求,除了下图的错误提示,本程序还可以提示的错误有:输入过多运算符,缺少反括号,两个括号之间缺少运算符相连,缺少左括号,输入的运算符超出范围等提示。

c语言表达式

c语言表达式

c语言表达式前言本文主要介绍什么是表达式,表达式在C语言中非常常见希望大家可以好好学习。

一、表达式定义表达式是一种有值的语法结构,它由运算符(变量、常量、函数调用返回值)结合而成,每个表达式一定有一个值。

二、常量表达式例子:a, 12, 12.4值:就是变量或者常量本身的值作为条件的时候非0即真,0即假三、算数表达式例子a+b c*d+a 12/3+d i++ --a值就是计算的结果作为条件的时候非0即真,0即假四、赋值表达式例子a=12 a+=12 a = c= d值赋值完a的值,即为结果作为条件的时候非0即真,0即假五、关系表达式例子a >b 2 ==3值:1和0(当表达式成立时返回一个1,表达式不成立时返回一个0)作为条件的时候非0即真,0即假六、逻辑表达式例子a && b(a与b)c||d(c或b)!a(非a)//具体后面文章讲解值:1和0(当表达式成立时返回一个1,表达式不成立时返回一个0)作为条件的时候非0即真,0即假七、复合表达式实质上就是一些算数运算结合在一起。

例子x = ( y = (a + b + a > 4), z=10) //就是平时的复合运算值:依据运算符优先级和结合性得到结果作为条件非0即真,0即假八、逗号表达式例子(1,2,3,4,a) //值为最右侧的也就是a值:最右侧的值是逗号表达式的结果作为条件的时候非0即真,0即假代码:#include<stdio.h>int main(void){int a=1,2,3,4;printf("%d\n",a);//结果是4return 0;}九、其他的有返回值的函数也是一个表达式(函数后面文章讲解)其他运算符总结表达式类型多种多样,希望大家好好理解。

(完整版)数学表达式计算(c语言实现)

(完整版)数学表达式计算(c语言实现)

一、设计思想计算算术表达式可以用两种方法实现:1.中缀转后缀算法此算法分两步实现:先将算术表达式转换为后缀表达式,然后对后缀表达式进行计算。

具体实现方法如下:(1)中缀转后缀需要建一个操作符栈op和一个字符数组exp,op栈存放操作符,字符数组用来存放转换以后的后缀表达式。

首先,得到用户输入的中缀表达式,将其存入str数组中。

对str数组逐个扫描,如果是数字或小数点,则直接存入exp数组中,当扫描完数值后,在后面加一个#作为分隔符。

如果是操作符,并且栈为空直接入栈,如果栈不为空,与栈顶操作符比较优先等级,若比栈顶优先级高,入栈;如果比栈顶优先级低或相等,出栈将其操作符存到exp数组中,直到栈顶元素优先等级低于扫描的操作符,则此操作符入栈;如果是左括号,直接入栈,如果是右括号,出栈存入exp数组,直到遇到左括号,左括号丢掉。

然后继续扫描下一个字符,直到遇到str中的结束符号\0,扫描结束。

结束后看op栈是否为空,若不为空,继续出栈存入exp数组中,直到栈为空。

到此在exp数组最后加结束字符\0。

我们就得到了后缀表达式。

(2)后缀表达式计算此时需要一个数值栈od来存放数值。

对exp数组进行逐个扫描,当遇到数字或小数点时,截取数值子串将其转换成double类型的小数,存入od栈中。

当遇到操作符,从栈中取出两个数,进行计算后再放入栈中。

继续扫描,知道扫描结束,此时值栈中的数值就是计算的结果,取出返回计算结果。

2.两个栈实现算法此算法需要两个栈,一个值栈od,一个操作符栈op。

将用户输入的数学表达式存入str数组中,对其数组进行逐个扫描。

当遇到数字或小数点,截取数值子串,将其转换成double类型的数值存入od栈中;当遇到左括号,直接入op栈;遇到右括号,op栈出栈,再从值栈od中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到操作符栈栈顶为左括号,将左括号丢掉。

如果遇到操作符,若op栈为空,直接入栈;若栈不为空,与栈顶元素比较优先等级,若比栈顶操作符优先等级高,直接入op栈,如果低于或等于栈顶优先等级,op栈出栈,再从值栈中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到栈顶优先等级低于扫描的操作符等级,将此操作符入op栈。

数据结构(C语言版)课程设计报告表达式求值说明书

数据结构(C语言版)课程设计报告表达式求值说明书

数据结构(C语言版)课程设计报告表达式求值说明书XX大学数据结构课程设计说明书题目:表达式求值院系:计算机科学与工程学院专业班级:计算机班学号:学生姓名:指导教师:2021年X月X日XX大学课程设计(论文)任务书计算机科学与工程学院学号学生姓名专业(班级)设计题目表达式求值设计技术参数系统平台:Windows7/WindowsXP开发工具:VC++6.0设计要求(1)能够计算的运算符包括:加、减、乘、除、圆括号。

(2)能够计算的数要求在实数范围内。

(3)能执行多重括号嵌套运算。

(4)对于异常表达式给出错误提示。

工作量课程设计报告要求不少于3000字。

源程序要求不少于300行工作计划2021.11.21-12.01根据课程设计大纲的要求,查找相关资料,完成需求分析;2021.12.02-12.16进行系统的概要设计;2021.12.17-12.31进行系统的详细设计和源代码的书写;2021.01.01-01.17对系统进行调试分析,写出课程设计报告。

参考资料[1]何钦铭主编.C语言程序设计.北京:高等教育出版社,2021.[2]谭浩强编著.C程序设计(第四版).北京:清华大学出版社,2021.[3]严蔚敏,吴伟民编著.数据结构(C语言版)北京:清华大学出版社,2021.[4]严蔚敏,吴伟民编著.数据结构题集北京:清华大学出版社,2021.指导教师签字教研室主任签字2021年X月X日学生姓名:学号:专业班级:课程设计题目:表达式求值指导教师评语:成绩:指导教师:年月日XX大学课程设计(论文)成绩评定表目录1需求分析12概要设计12.1设计思路12.2存储结构设计12.3功能模块设计13详细设计14运行与测试15总结1参考文献2(要求:给出一级目录和二级目录,宋体,四号字,1.5倍行距,页码使用罗马数字,居中)(报告正文部分):(要求:正文部分一律用小四号字,宋体,行距20磅。

一级标题靠左,加粗。

二级大标题靠左,不加粗。

数据结构C语言版_栈实现表达式求值

数据结构C语言版_栈实现表达式求值
c=getchar();
break;
case'=':
Pop(&OPTR,&x); // 脱括号并接收下一字符
c=getchar();
break;
case'>':
Pop(&OPTR,&theta); // 退栈并将运算结果入栈
switch(theta)
{
case'+':
c=a+b+48;
break;
case'-':
c=a-b+48;
break;
case'*':
c=a*b+48;
break;
case'/':c=a/b+48;
}
return c;
}
// 算法3.4 P54
}SqStack; // 顺序栈
// 构造一个空栈S。
int InitStack(SqSt的存储空间
(*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
default:
f='>';
}
}
return f;
}
// 判断c是否为运算符
int In(SElemType c)
{
switch(c)
{
case'+':
case'-':
case'*':

C语言_算术表达式求值_代码

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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*表达式求值,输入一个表达式,如1+2*3#,程序可计算出结果为7 支持以下符号:+ - * / ( ) ^ .可以计算整数、小数其中^表示次方,2^5表示2的5次方*//*头文件*/#include <stdio.h>#include <malloc.h>#include <string.h>#include <math.h>#include <stdlib.h>/*宏定义*/#define INIT_STACK_SIZE 100#define SET_NUM 8#define N 100/*字符优先级表*/unsigned char prior[SET_NUM][SET_NUM] ={/* '+' '-' '*' '/' '(' ')' '#' '^' *//*'+'*/'>', '>', '<', '<', '<', '>', '>', '<',/*'-'*/'>', '>', '<', '<', '<', '>', '>', '<',/*'*'*/'>', '>', '>', '>', '<', '>', '>', '<',/*'/'*/'>', '>', '>', '>', '<', '>', '>', '<',/*'('*/'<', '<', '<', '<', '<', '=', ' ', '<',/*')'*/'>', '>', '>', '>', ' ', '>', '>', '>',/*'#'*/'<', '<', '<', '<', '<', ' ', '=', '<',/*'^'*/'>', '>', '>', '>', '<', '>', '>', '>'};unsigned char priorSet[SET_NUM] = {'+', '-', '*', '/', '(', ')', '#', '^'};/*结构体定义,这是用来存放字符的栈*/typedef struct{char *base;char *top;int stacksize;} SqStackC;/*结构体定义,这是用来存放数字的栈*/typedef struct{double *base;double *top;int stacksize;} SqStackN;void initStackN(SqStackN &);void initStackC(SqStackC &);void pushN(SqStackN &, double);void pushC(SqStackN &, double);void popN(SqStackN &, double &);void popC(SqStackN &, double &);double calculate(double, char, double);int findInSet(char);char compare(char, char);void getSolution();/*主函数*/void main(){getSolution();}/*初始化数字栈*/void initStackN(SqStackN &S){S.base = (double*) malloc(INIT_STACK_SIZE * sizeof(double));S.top = S.base;S.stacksize = INIT_STACK_SIZE;}/*初始化字符栈*/void initStackC(SqStackC &S){S.base = (char*) malloc(INIT_STACK_SIZE * sizeof(char));S.top = S.base;S.stacksize = INIT_STACK_SIZE;}/*向数字栈中存放数字*/void pushN(SqStackN &S, double x){if (S.top-S.base >= S.stacksize)*(S.top++) = x;}/*向字符栈中存放字符*/void pushC(SqStackC &S, char x){if (S.top - S.base >= S.stacksize)return;*(S.top++) = x;}/*从数字栈中取出数字*/void popN(SqStackN &S, double &x){if (S.top==S.base)return;x = *(--S.top);}/*从字符栈中取出字符*/void popC(SqStackC &S, char &x){if (S.top == S.base)return;x = *(--S.top);}/*这个函数返回a operation b的值。

假如operation为'+',则返回a+b的值*/ double calculate(double a, char operation, double b){/*判断operation,返回对应的计算结果*/switch (operation) {case '+':return a + b;case '-':return b - a;case '*':return a * b;case '/':return b / a;case '^':return pow(b, a);default:}}/*查找字符c在priorSet中的什么位置*//*priorSet是所支持的所有字符的集合*/int findInSet(char c){int i;for (i = 0; i < SET_NUM; i++) {if (priorSet[i] == c)return i;}return -1;}/*比较optrtop和c的优先关系*/char compare(char optrtop, char c){int i, j;/*从priorSet中取出optrtop和c的位置*/i = findInSet(optrtop);j = findInSet(c);/*如果返回值中有-1表示这个符号不支持,结束程序*/if (i == -1 || j == -1) {printf("不支持的符号类型\n");exit(0);}/*否则返回二者优先级关系*/elsereturn prior[i][j];}/*取得计算结果*//*解释下代码处理数字的原理:假如输入为10+2.2*3-2#循环会从这个字符串第一个位置开始,也就是1如果当前字符是个数字,则要把这个数字从字符串里取出来这个时候涉及两个问题,一是数字可能是大于10的整数,二是可能有小数。

处理方法是这样的:当遇到数字,先将数字保存在n上,判断下一个字符是数字还是运算符如果是数字,则将n乘以10加上这个数字,这样即可以处理大于10的数字。

如果遇到运算符,就退出循环去处理运算符如果遇到的是小数点,表示这个数字是小数。

小数不会立刻计算出来,而是先将小数点忽视掉,将整数计算出。

比如2.2会先计算成22变量j和begin在遇到小数点时候用来计算小数点后面有几个数字,即这个小数有多少位。

当begin = 1时候,表示现在要计算小数点后的数字位数。

这时候j会在每次循环加1 这样计算后,n = 22, j = 1;此时算n = n / pow(10, j);即将n缩小10的j次方。

就变成了2.2*/void getSolution(){/*operation是当前的运算符*/char operation;/*temp是输入的字符串*/char temp[N];/*i是循环变量,j和begin用来控制什么时候计算出小数*/int i = 0, j = -1, begin = 0;/*sum是每次的计算结果,a和b是从数字栈中取出的数字,n用来存放从字符串中取出的数*/double sum, a, b, n;/*定义堆栈并初始化*/SqStackC OPTR;SqStackN OPND;initStackC(OPTR);initStackN(OPND);/*向字符栈中压入#,标志开始*/pushC(OPTR, '#');/*获得输入*/printf("请输入一个表达式,输入#结束\n");gets(temp);/*开始计算,当遇到#表示结束*/while (temp[i] != '#' || *(OPTR.top - 1) != '#') {/*如果当前字符是个数字字符*/if (temp[i] >= '0' && temp[i] <= '9') {/*重置n为0*/n = 0;/*当当前字符是数字或者小数点*/while (temp[i] >= '0' && temp[i] <= '9' || temp[i] == '.') {/*如果是小数点,begin=1,表示要从字符串中取出一个小数*/if (temp[i] == '.')begin = 1;/*否则作为整数取出*/elsen = n * 10 + temp[i] - '0';/*如果begin不为0,表示遇到了一个小数点,表示需要合并为小数*//*j表示这个小数的小数点后面有几位*/if (begin != 0)j++;/*循环变量加1*/i++;}/*如果j不为-1,则表示这是个小数,n是整数结果,除以pow(10,j)则变成了小数*/if (j != -1)n = n / pow(10, j);/*将数字压入栈*/pushN(OPND, n);/*重置j和begin的值*/j = -1;begin = 0;}else {/*如果当前字符不是数字,比较栈顶字符和当前字符优先级,根据优先级处理*/switch (compare(*(OPTR.top - 1), temp[i])) {/*如果栈顶字符优先级大,则可以取出计算*/case '>':/*取出字符栈顶运算符,和数字栈顶的两个数字*/popC(OPTR, operation);popN(OPND, a);popN(OPND, b);/*计算结果*/sum = calculate(a, operation, b);/*结果入栈*/pushN(OPND, sum);break;/*如果优先级小*/case '<':/*入栈,继续循环*/pushC(OPTR, temp[i]);i++;break;/*如果优先级相等*/case '=':/*优先级相等只有两个可能,#相遇或者()相遇,这情况只要把字符出栈丢掉就可以了,因为已经没用了*/popC(OPTR, operation);i++;break;}}}/*输出结果*/printf("结果为:%lf\n", *(OPND.top - 1));}。

相关文档
最新文档