问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C/C++ 语言中的表达式求值

发布网友 发布时间:2022-05-01 18:26

我来回答

1个回答

热心网友 时间:2022-06-21 05:02

#include "stdio.h"
#include "malloc.h"

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//构造一个空栈
Status 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;
}
//判断是否为空栈
Status StackEmpty(SqStack S){
if(S.top == S.base)
return TRUE;
else
return FALSE;
}
//用e返回S的顶元素
Status GetTop(SqStack S, SElemType *e){
if(S.top == S.base)
return ERROR;
*e = *(S.top-1);
return OK;
}
//插入e为新的顶元素
Status Push(SqStack *S, SElemType e){
if((S->top - S->base) >= S->stacksize){
S->base = (
SElemType*)realloc(S->base,
(S->stacksize+STACKINCREMENT)*sizeof(SElemType)
);
if(!S->base)
exit(OVERFLOW);
S->top = S->base +S->stacksize;
S->stacksize += STACKINCREMENT;
}
*(S->top)=e;
S->top++;
return OK;
}
//删除S的顶元素,并用e返回其值
Status Pop(SqStack *S, SElemType *e){
if(S->top == S->base)
return ERROR;
S->top--;
*e = *(S->top);
return OK;
}
//从栈底到栈顶依次对S的每个元素调用函数Visit(),一旦失败操作无效
Status ListTraverse(SqStack S,Status (*visit)(SElemType)){
SElemType *p;
p=S.base;
for(p=S.base;p<S.top;p++)
(*visit)(*p);

return OK;
}
//输出元素e
Status output(SElemType e){
printf("%d ",e);

return OK;
}

实现表达式求值的代码:
/*计算整数表达式的值
*表达式必须以#结束
*表达式中可以出现多位数字,
*表达式中可以出现空格
*运算符包括+,-,*,/,(,)
*运算结果可以是多位整数,并以整数的形式返回
*/
typedef int SElemType; /*放入堆栈的元素的类型*/
#include <ctype.h>
#include "stack_s.c"
/*判断输入的某个字符是否是运算符
*c表示输入的字符
*op数组中存放系统能识别的运算符
*/
Status in(char c,char op[]){
char *p;
p=op;
while(*p != '\0'){
if(c == *p)
return TRUE;
p++;
}
return FALSE;
}
/*比较两个运算符的优先级
*a,b中存放待比较的运算符
*'>'表示a>b
*'0'表示不可能出现的比较
*/
char Precede(char a, char b){
int i,j;
char pre[][7]={
/*运算符之间的优先级制作成一张表格*/
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}};
switch(a){
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(b){
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];
}
/*进行实际的运算
*a,b中分别以整数的形式存放两个待运算的操作数
*theta中存放代表操作符的字符
*结果以整数的形式返回
*/
int Operate(int a, char theta, int b){
int i,j,result;
i=a;
j=b;

switch(theta) {
case '+': result = i + j; break;
case '-': result = i - j; break;
case '*': result = i * j; break;
case '/': result = i / j; break;
}
return result;
}
/*从输入缓冲区中获得下一个整数或运算符,并通过n带回到主调函数
*返回值为1表示获得的是运算符
*返回值为0表示获得的是整形操作数
*/
int getNext(int *n){
char c;
*n=0;
while((c=getchar())==' '); /*跳过一个或多个空格*/
if(!isdigit(c)){ /*通过函数判断如果字符不是数字,那么只能是运算符*/
*n=c;
return 1;
}
do { /*能执行到该条语句,说明字符是数字,此处用循环获得连续的数字*/
*n=*n*10+(c-'0'); /*把连续的数字字符转换成相对应的整数*/
c=getchar();
} while(isdigit(c)); /*如果下一个字符是数字,进入下一轮循环*/
ungetc(c,stdin); /*新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区*/
return 0;
}

int EvaluateExpression(){

int n;
int flag;
int c;
char x,theta;
int a,b;

char OP[]="+-*/()#";
SqStack OPTR;
SqStack OPND;

InitStack(&OPTR);
Push(&OPTR,'#');
InitStack(&OPND);
flag=getNext(&c);

GetTop(OPTR, &x);
while(c!='#' || x != '#')
{
if(flag == 0)
{
Push(&OPND,c);
flag = getNext(&c);
} else
{
GetTop(OPTR, &x);
switch(Precede(x, c))
{
case '<'://栈顶元素优先级低
Push(&OPTR,c);
flag = getNext(&c);
break;
case '='://脱括号并接受下一字符
Pop(&OPTR,&x);
flag = getNext(&c);
break;
case '>':// 退栈并将运算结果入栈
Pop(&OPTR, &theta);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND, Operate(a, theta, b));
break;
}
}
GetTop(OPTR, &x);
}
GetTop(OPND, &c);
return c;
}

void main(){
int c;
printf("Please input one expression:");
c=EvaluateExpression();
printf("Result=%d\n",c);
getch();
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
行车工退休是否有工龄年限限制?男士、女士的的退休年龄。 北京中新惠尔健康科技有限公司解决方案 北京中新惠尔健康科技有限公司公司文化 北京中新惠尔健康科技有限公司服务产品 北京中新惠尔健康科技有限公司历史沿革 北京中新惠尔健康科技有限公司惠尔简介 速腾能放多久? 昆山汽车搭电多少钱? 比亚迪救急估计电瓶没电了 盒马员工超过1小时算不算大吧 人在国外如何充值中国移动话费?你好,我在非洲刚果金能给自己手机充值话费吗 Oracle空间操作函数SDO_RELATE和SDO_GEOM.RELATE的关系和区别是什么... 联想存储的特点是 findcounters用的什么算子 C++编程endl的用法 电梯事件妈妈是怎么死的?绞死了还有完整的身体吗? oppoa92s微信视频录屏怎么录不到对方的声音? “公鸡多了不下蛋”这句话是什么意思? 问世界上是人多还是鸡多? oracle 怎么查看 ewallet.p12 的内容 双卡手机怎么显示sim卡信息只能存50条 做大葱炒肉放什么调料 怎么让无sim卡的手机显示有卡? 三星S5830怎么把sim卡上的手机号码显示出来 怎样能把sim卡上的短信弄出来 怎么把SIN卡信息显示出来? 一加手机8pro怎么样?用着流畅吗? 一加10pro游戏模式找不到了 一加8pro游戏空间后面是什么图标 一加8Pro可以玩pokemmo吗? 人在国外如何充值移动,电信,联通手机话费,有什么热线可以充值吗? iphone 里面wallet是什么意思? 在国际漫游状态下没有话费了,可以充值吗? 基于matlab的边缘检测的robert算子的算法?怎么写? 如何在国内给国外的手机充值? error C2678: 二进制“&gt;&gt;”: 没有找到接受“std::istream”类型的左操作数的运算符(或没有可接受的转换) vc图像处理Robert算子源代码有点看不懂,请教高手帮我解答一下 我想问一下,怎么能不重载运算符,就输出一个模板返回来的字符数组,是要变成字符流吗?求求大佬解答 新电脑装完系统后一直转圈圈 c语言运算符简单问题 朋友在美国,手机卡是中国的,需要充值话费,要怎么充值啊 取地址运算是什么意思 在国内如何给国外的手机号码充值? 电话卡是广州的,人在美国怎么充值电话费? uc浏览器是32位还是64位 急急急!我在海外怎么给用外币给自己的充值电话费? win7 32位系统 用什么浏览器好??用uc浏览器好吗? WIN732位用什么浏览器比较好??用uc浏览器好吗? 没有64位的UC浏览器么 在国内能给国外的电话卡充值吗