首页 > 编程知识 正文

利用栈表达式求值c语言代码,C语言复杂表达式求值

时间:2023-05-06 19:51:04 阅读:22374 作者:2222

创建函数目录(堆栈的基本操作)堆栈,然后创建初始化(create )堆栈(push_In )外堆栈(pop_out )堆栈顶部元素(GetTop )优先级函数) Precede

http://www.Sina.com/http://www.Sina.com /

运算数为整数型,而运算符为字符型,存储在谈谈我遇到的问题:1.该选择数字栈还是字符栈?中时,为‘0’‘9’的选用字符栈的数字也表明,即使运算过程中的中位数超过2位,由于将操作数转换为字符形态进行堆栈计算,不仅字符堆栈中的界限相当大,无法输入0-9以上的数字,同时在操作数运算过程中也不会出现2位选择字符形式(整数)可将任何数字顺利存储在堆栈中,但在存储无法存取两位以上时,将其转换为无法运算两位以上的形式

请先确信这是可能的! 但是,要创建两种不同类型的堆栈,必须在代码中写两次堆栈的基本操作函数(构建、初始化、堆栈、外堆栈、堆栈顶部元素),然后在访问操作数和运算符时分别调用相应的操作过程太麻烦,代码也太复杂,没有数字堆栈那么简单。无法

输入方式1 :请输入公式:3*(5-2)

输入法2 :请输入表达式。 3*(5—2)第一种输入法直接打出公式输入整个内容,第二种输入法逐个读取。 第一种输入法可以直接创建数组char str[ ]并在gets(str )中输入,表达式的输入非常直观。 如果是第2种输入方式,则是通过getchar ()读取1位,公式的输入并不比第1种直觉方便。

数字栈

使用GETS(str )或scanf执行字符串读取表达式后,存储如下:

多位存储方法:

我们用str[i]进行逐位访问,I; 要实现逐位偏移,请访问操作符; 必须注意的是,对于多位内存,由于使用ASCII码,因此只能使用数字栈

2.若建立两个栈,一个数字栈用来存放运算数,一个字符栈用来存放操作符,是否可行?

现在,在处理多位的情况下,提出“合并”的思想,首先是3.表达式输入方式的选取4.选择了以字符串的形式输入表达式后,表达式会如何存储?将如何访问?读取各位数字,str[i++]; 实现将http://www.Sina.com/数字以字符形式存入字符数组操作数合并到http://www.Sina.com /。 那么,首先读取第一位的数字,放入X1,然后放入X2,(第一次合并完成后)接着让X1读取下一个字符,如果X1还是数字(X1是否是数字可以由isdigital判断),则合并操作http://(第二次合并操作已完成),接着让X1读取下一个字符,如果保持数字,则继续合并)第三次合并已完成)。 这样,如果下一位字符是数字,则合并一次。

例如,在34*5473的情况下,X1读取3,并将其合并为X2 (在第一次合并的情况下,X1=3; X2=3)接着,让X1读取4,识别X1是数字,合并到X2 (第二次合并,此时X1=4; X2=34 ),注意到下一位不是数字,停止读取并返回X2的值34以合并到堆栈中。 因此,我们递归地成功地将34读取到堆栈中,接下来看看如何读取4位数字5473,首先读取X1,合并x2 (x2=5),然后读取X1,X1是数字X2=54 ),继续向X1读取7,合并为X2 (第三次合并,此时X1=7; X2=547 ),接着让X1读取3,合并到X2 (第三次合并,此时X1=3; X2=5473 ),读取完成,返回X2的值5473并合并到堆栈中。

一个单元格存一位数字

优先级函数用二维数组存储优先级表,用分支结构定位二维数组的矩阵坐标,这种写法看起来繁琐、简洁、直观。 优先级函数也可以写逻辑表达式,代码量少但逻辑分析过程复杂,出现错误难以调试,维护成本太高,总的来说是可行的方法,但不是聪明的做法

法。

7.在运算除法时,若除数为0,如何给做出错误反馈?
在Operate求值函数中,当theta是除号时,先用 if 判断如果除数为0,则返回错误结果,否则进行除法运算。

8.在检测到输入的字符是非法字符时如何给出错误反馈?在检测到输入字符是一个或多个空格时如何自动跳过空格?
在evaluateExpression函数中,只需要添加两组与判断是否为运算符的if、判断是否为数字的if相平行的if来判断输入是否为空格,若为空格,则直接跳过读取下一位字符,若既不是数字,不是运算符,也不是空格,即为非法字符,返回错误提示。

注意: 表达式的输入必须以“=”结束
输入示例:3*(5-2)=输入格式可以有空格,但是唯一的BUG是在多位数的每一位之间加空格会出错!isdigit是包含在头文件ctype.h中的判断是否为数字的函数,是数字返回1,不是返回0。此算法用于计算整型,若要计算浮点数,把相应的类型更换成double即可实现。算法运算逻辑是先以字符型读入字符数组中,再将字符型转换为整型存入数字栈中。 完整源代码 #include <stdio.h>#include <stdlib.h>#include <ctype.h> #define Maxsize 100typedef int dataType; typedef struct Stack{dataType *top;dataType *base;int stacksize;}sqstack;void create(sqstack *s){ s->base=(dataType *)malloc(Maxsize*sizeof(dataType)); if(!s->base) { printf("Space allocation failed!n"); return; } s->top=s->base; s->stacksize=Maxsize; return;}int push_in(sqstack *s,dataType value){if(s->top-s->base==s->stacksize){printf("Stack is full!n");return;}*s->top=value; //"*s->top++=value;"s->top++;return;}int pop_out(sqstack *s,dataType *elem){if(s->base==s->top){printf("Stack is empty!");return;}s->top--;*elem=*s->top; //"*elem=*--s->top;"return;}dataType GetTop(sqstack *s) {if(s->base==s->top){ printf("Stack is empty!n"); printf("Unable to fetch top stack element!n"); return;} return *(s->top-1);}char Precede(char theta1,char theta2){int i,j;char pre[7][7]={// + - * / ( ) = {'>','>','<','<','<','>','>'}, {'>','>','<','<','<','>','>'}, {'>','>','>','>','<','>','>'}, {'>','>','>','>','<','>','>'}, {'<','<','<','<','<','=','0'}, {'>','>','>','>','0','>','>'}, {'<','<','<','<','<','0','='}}; switch(theta1){ 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(theta2){ 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(pre[i][j]);}int Operate(int a,char theta,int b){int result;switch(theta){case'+':return a+b;case'-':return a-b;case'*':return a*b;case'/': //判断除数是否为0,若除数为零返回错误提示 if(b!=0) return a/b; else { printf("Divisor can not Be zero!n"); exit(0);}} }int In(char c) //判断是否为运算符,是运算符返回1,若不是返回0{switch(c){case '+': case '-': case '*': case '/': case '(': case ')': case '=': return 1; default: return 0; }}int evaluateExpression(char exp[]) {sqstack OPND,OPTR; //运算数栈、运算符栈dataType a,b,theta,x,X1,X2; /* a,b,theta用于Operate函数 X用于存放多余的出栈字符 X1,X2用于归并 */char ch; //读取字符的变量int i=0; //指向存放表达式数组的下标指针(其实不是真正的指针,而是数组下标)create(&OPND); //建立并初始化运算数栈OPNDcreate(&OPTR); //建立并初始化运算符栈OPTRpush_in(&OPTR,'='); //先将“=”号压入OPTR栈(表达式也必须以“=”结束)ch=exp[i++]; //ch读取字符数组第一个元素,并将指针i后移一位while(ch!='='||GetTop(&OPTR)!='=') //表达式没有扫描完毕或OPTR的栈顶不为“=”{if(In(ch)) //判断ch是否为操作符{switch(Precede(GetTop(&OPTR),ch))//比较ch的与OPTR栈顶元素的优先级{case'<': push_in(&OPTR,ch); ch=exp[i++]; //读取下一位字符并将指针向后偏移一位 break;case'>': pop_out(&OPTR,&theta); pop_out(&OPND,&b); pop_out(&OPND,&a); push_in(&OPND,Operate(a,theta,b)); break;case'=': pop_out(&OPTR,&x); ch=exp[i++]; //读取下一位字符并将指针向后偏移一位 break;}}else if(isdigit(ch)) //判断是否为数字{X1=ch-'0'; //将字符形式转化为数字push_in(&OPND,X1);X2=X1;ch=exp[i++]; //读取下一位字符并将指针向后偏移一位while(isdigit(ch)) //判断下一位是否还是数字{X1=ch-'0';X2=10*X2+X1; //归并至X2pop_out(&OPND,&x);push_in(&OPND,X2);ch=exp[i++]; //读取下一位字符并将指针向后偏移一位} } else if(ch==' ') //判断是否为空格{while(ch==' ') //跳过若干个空格{ch=exp[i++]; //忽略空格,直接取下一位}}else //若不是上述三种情况之一,则为非法字符{printf("Input has illegal characters!n");printf("Please enter again.n");exit(0); //返回错误提示}}return(GetTop(&OPND)); //最后返回操作数栈顶为运算结果}int main(){ char exp[100]; //定义一个字符数组用于存储表达式 int result; printf("Please Enter Expression:"); gets(exp); //换成scanf(“%s”,exp);也可以 result=evaluateExpression(exp); printf("n"); printf("%s%dn",exp,result); return 0;} 执行结果:

参考: 数据结构(C语言第二版)——mmdsj栈的经典应用——yuluows栈的应用(表达式求值)——Sup_klz

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。