★观前提示:本篇内容为数据结构实验,代码内容经测试没有问题,但是可能会不符合每个人实验的要求,因此以下内容建议仅做思路参考。
一、实验目的
掌握栈与队列的基本结构和操作方法,并能利用其解决实际问题。
二、实验要求
输入一个表达式(4+2*4#) ,利用栈求表达式的值。(只对整数求值,目前只考虑操作数为个位数的情况,即 24 + 34 * 34 这种情况不考虑)
思路提示:
1、先实现栈的基本操作:初始化,入栈,出栈等。 2、首先将一个中缀式变成后缀式,然后,对后缀式求值。 3、可用顺序栈或者链栈实现。
★温馨提示:以下代码均为改正过的代码,皆已经过测试。
三、源码实现
#include<stdio.h>
#include<iostream>
#include<malloc.h> //头文件
#include<stdlib.h>
using namespace std;
#define SetType int
#define Status int
#define STACKINC 10
#define STACKSIZE 100 //最大SIZE设置为100
//运算符优先级表
char Prior[7][7] =
{ // '+' '-' '*' '/' '(' ')' '#'
/*'+'*/'>','>','<','<','<','>','>', //当栈中的符号是加号时,此加号与下一个运算符进行比较优先级
/*'-'*/'>','>','<','<','<','>','>', //下面几行类似
/*'*'*/'>','>','>','>','<','>','>',
/*'/'*/'>','>','>','>','<','>','>',
/*'('*/'<','<','<','<','<','=',' ',
/*')'*/'>','>','>','>',' ','>','>',
/*'#'*/'<','<','<','<','<',' ','='
};
//判断优先级函数
char Precede(int a, int b) {//判断优先级
return Prior[a][b];
}
//顺序栈 结构体
typedef struct {
SetType *base;
SetType *top;
int stacksize;
}SqStack;
//构造空栈S
Status InitStack(SqStack &S) {
S.base = (SetType *)malloc(STACKSIZE * sizeof(SetType));
if (!S.base) return -1;
S.top = S.base;
S.stacksize = STACKSIZE;
return 1;
}
//入栈操作
Status Push(SqStack &S, SetType e) {
if (S.top - S.base >= S.stacksize) { //栈满,追加空间
S.base = (SetType *)realloc(S.base, (S.stacksize + STACKINC) * sizeof(SetType));
if (!S.base) return 0; //存储空间分配失败
S.top = S.base + S.stacksize;
S.stacksize += STACKINC;
}
*S.top = e;
S.top++;
return 1;
}
//出栈操作
Status Pop(SqStack &S, SetType &e) {
if (S.top == S.base) return 0;
e = *--S.top;
return e;
}
//取栈顶元素
Status GetTop(SqStack S, SetType &e) {
if (S.top == S.base) { //如果栈为空,返回错误
return 0;
}
e = *(S.top - 1);
return e;
}
//转换函数
int change(char a) { //将字符转换成数字
if (a == '+') return 0; //主要是因为建立的栈为int型
if (a == '-') return 1; //方便与存储到栈中
if (a == '*') return 2;
if (a == '/') return 3;
if (a == '(') return 4;
if (a == ')') return 5;
if (a == '#') return 6;
else return a-48;
}
//判断是不是运算符
int In(char c) {
if (c-48>=0 && c-48<= 9) return 0;
else return 1;
}
//进行运算
int Operator(int a, int theta, int b) {
if (theta == 0) return a + b;
if (theta == 1) return a - b;
if (theta == 2) return a*b;
if (theta == 3) return a/b;
}
//输入表达式并求值
int EvaluateExperession() {
SqStack optr; //运算符栈
SqStack opnd; //运算数栈
InitStack(optr); //初始化
InitStack(opnd); //初始化
Push(optr, 6); //初始栈底元素为#,用数字6表示
char c[50]; //用字符串数组来保存输入的表达式
int i=0, x, result;
cin>>c; //输入表达式
do
{
if (!In(c[i])) { //如果不是运算符,将其进运算数栈
Push(opnd, change(c[i]));
i++;
}
else { //是运算符,比较优先级并进行相关操作
switch (Precede(GetTop(optr, x), change(c[i]))) {
case '<': //当前栈顶元素优先级低,新运算符入栈
Push(optr, change(c[i]));
i++;
break;
case '=': //两个运算符相等,为左右括号,取出
Pop(optr, x);
i++;
break;
case '>': //当前栈顶运算符优先级高,进行计算
int a, b, theta;
Pop(optr, theta); //取当前栈顶运算符
Pop(opnd, b); //取栈顶运算数b,并从栈中删除
Pop(opnd, a); //取栈顶运算数a,并从栈中删除
Push(opnd, Operator(a, theta, b)); //进行计算,将计算结果
break;
}
}
} while ( c[i] );
return GetTop(opnd, result);
}
//主函数
int main()
{
printf("请输入一个表达式(以#结束):");
cout<<EvaluateExperession();//调用表达式函数
return 0;
}
2022.5.21记录:Code_流苏 如有任何疑问,评论回复,看到即回,欢迎大家多多交流学习! ★以上实验内容仅供参考。