ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构实验之——栈的应用:算数表达式求值问题(不带括号情况)

2021-01-26 22:59:57  阅读:198  来源: 互联网

标签:case SElemType return top break 括号 base 求值 数据结构


算数表达式求值问题

不带括号情况

【设计要求】输入包含±*/四种运算(不含有()括号的合法算术表达式,且操作数为1位整数,并计算其值,表达式以#开始,并以#结束)。计算算术表达式的值,并输出。运算符号的优先级对比如下表所示:
在这里插入图片描述

代码示例

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量

typedef char SElemType;
typedef char OperandType; //表达式求值的运算类型
typedef int Status;

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)
{
printf(“内存分配失败!\n”);
exit(OVERFLOW);
}
S->top = S->base;
S->stacksize = STACKINCREMENT;
return OK;
}
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 >= STACK_INIT_SIZE) //栈满, 追加存储空间
{
S->base = (SElemType*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S->base)
{
printf(“内存分配失败!\n”);
exit(OVERFLOW);
}
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = e;
return OK;
}

Status Pop(SqStack* S, SElemType* e)
{
if (S->top == S->base)
return ERROR;
*e = *–S->top;
return OK;
}

Status StackDestroy(SqStack* S)
{
free(S->base);
S->base = NULL;
S->top = NULL;
S->stacksize = 0;
return OK;
}
void ClearStack(SqStack* S)//清空栈S,保留栈底指针
{
S->top = S->base;
}

char Precede(char c1, char c2) { //运算符之间的优先级制作成一张表格
int i, j;
char pre[][5] = {
{’>’,’>’,’<’,’<’,’>’},
{’>’,’>’,’<’,’<’,’>’},
{’>’,’>’,’>’,’>’,’>’},
{’>’,’>’,’>’,’>’,’>’},
{’<’,’<’,’<’,’<’,’=’} };
switch (c1) {
case ‘+’: i = 0; break;
case ‘-’: i = 1; break;
case ‘’: i = 2; break;
case ‘/’: i = 3; break;
case ‘#’: i = 4; break;
}
switch (c2) {
case ‘+’: j = 0; break;
case ‘-’: j = 1; break;
case '
’: j = 2; break;
case ‘/’: j = 3; break;
case ‘#’: j = 4; break;
}
return pre[i][j];
}
//判断c是否为运算符
Status In(OperandType c)
{
switch ©
{
case ‘+’:
case ‘-’:
case ‘*’:
case ‘/’:
case ‘#’:
return TRUE;
default:
return FALSE;
}
}

//二元运算(a theta b)
OperandType Operate(OperandType a, OperandType theta, OperandType b)
{
OperandType c = ‘\0’;
switch (theta)
{
case ‘+’:
c = a + b;
break;
case ‘-’:
c = a - b;
break;
case ‘*’:
c = a * b;
break;
case ‘/’:
c = a / b;
break;
}
return c;
}

//算术表达式求值的算符优先算法,设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合
OperandType EvaluateExpression()
{
SqStack OPTR, OPND;
OperandType a, b, d, x, theta;//theta 就是计算符 operate()的传值
char c; //存放有键盘输入的字符串
char z[6]; //存放整数字符串
int i;
InitStack(&OPTR);
Push(&OPTR, ‘#’); //#是表达式结束符
InitStack(&OPND); //初始化运算数栈
c = getchar();//字符串传入
GetTop(&OPTR, &x);
if (c == ‘#’ && x == ‘#’) {//接收一开始传进来的那个#
c = getchar();
}
else {//检查第一个传进来的第一个字符是不是#
printf(“抱歉,请检查输入的第一个字符是否是“#”!\n”);
exit(1);//异常
}
while (c != ‘#’ || x != ‘#’)
{
if (In©) //是7种运算符之一
{
switch (Precede(x, c))
{
case ‘<’: //当前已经压栈一个运算符(x)比后一个运算符(c)低时,就将c压栈
Push(&OPTR, c);
c = getchar();
break;
case ‘>’:
Pop(&OPTR, &theta); //退栈并将运算结果压入OPND中
Pop(&OPND, &b);
Pop(&OPND, &a);
Push(&OPND, Operate(a, theta, b));
break;
}
}
else if (c >= ‘0’ && c <= ‘9’) //c是操作数
{
i = 0;
do
{
z[i] = c;
i++;
c = getchar();
} while (c >= ‘0’ && c <= ‘9’);
z[i] = 0;
d = atoi(z); //将字符数组转为整型存于d
Push(&OPND, d);
}
else //c为非法字符
{
printf(“抱歉,有识别到非法字符,请检查你的输入!\n”);
exit(1);
}
GetTop(&OPTR, &x);
}
GetTop(&OPND, &x);
StackDestroy(&OPTR);
StackDestroy(&OPND);
return x;
}

int main()
{
printf("\t\t\t\t\t\t欢迎使用算术表达系统!\n");
printf("\t\t\t\t请输入算术表达式,负数要用(0-正数)表示!输入以#结束,请不要输入括号!:\n");
printf("%d\n", EvaluateExpression());
printf("\t\t\t\t\t\t感谢使用!\n");
return 0;
}

测试用例

在这里插入图片描述
在这里插入图片描述

标签:case,SElemType,return,top,break,括号,base,求值,数据结构
来源: https://blog.csdn.net/Xmumu_/article/details/113201160

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有