问题描述]
表达式求解是实现程序设计的基本问题之一,也是栈的应用的一个典型例子。设计一个程序用算符优先法求解表达式的值。
[基本要求]
以字符序列的形式从键盘输入语法正确的、不含变量的整数表达式,利用教科书表3.1给出的算符优先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例3-1演示在求值过程中运算符栈、运算数栈、输入字符和主要操作的变化过程。
[实现提示]
(1)设置运算符栈和运算数栈辅助分析算符优先关系;
(2)在读入表达式的序列的同时,完成运算符合运算数(整数)的识别处理,以及相应的运算;
(3)在识别出运算数的同时,要将其字符序列形式转换成整数形式;
(4)在程序的适当位置输出运算符栈、运算数栈、输入字符和主要操作的内容
首先了解下算数优先级:
设计过程:
数据类型定义:
1.顺序栈定义
typedef struct sqstack
{//顺序栈结构
elemtype stack[MAXSIZE];
int top;
}sqstsck;
2.全局变量定义:
char ch[8]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; //把符号转换成字符数组
int f1[7]={3,3,5,5,1,6,0}; //栈内元素优先级
int f2[7]={2,2,4,4,6,1,0}; //栈外元素优先级
int n=0;
源程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<ctype.h> //判断是否为字符函数的头文件
#define MAXSIZE 100
typedef int elemtype;
char ch[8]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'}; //把符号转换成字符数组
int f1[7]={3,3,5,5,1,6,0}; //栈内元素优先级
int f2[7]={2,2,4,4,6,1,0}; //栈外元素优先级
int n=0;
typedef struct sqstack
{//顺序栈结构
elemtype stack[MAXSIZE];
int top;
}sqstsck;
//1.把操作符转换为相应数字
elemtype cton(char c)
{
switch(c)
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
default: return 6;
}
}
//2.比较字符优先级
char Compare(char c1,char c2)
{
int i1=cton(c1);
int i2=cton(c2); //把字符变成数字
if(f1[i1]>f2[i2]) return '>'; //通过原来的设定找到优先级
else if(f1[i1]<f2[i2]) return '<';
else return '=';
}
//3.四则运算
int Operate(elemtype a,elemtype t,elemtype b)
{
int sum;
switch(t)
{
case 0: sum=a+b; break;
case 1: sum=a-b; break;
case 2: sum=a*b; break;
default: sum=a/b;
}
return sum;
}
//5.取栈顶元素
elemtype Gettop(sqstack s)
{
if(s.top ==0)
{
printf("ERROR,underflow\n");
return 0;
}
else return s.stack[s.top];
}
//6.初始化
void Initstack(sqstack *s)
{
s->top =0;
}
//7.出栈
void Pop(sqstack *s,elemtype *x)
{
if(s->top ==0) printf("ERROR,underflow!\n");
else
{
*x=s->stack [s->top];
s->top--;
}
}
//8.入栈
void Push(sqstack *s,elemtype x)
{
if(s->top ==MAXSIZE-1) printf("ERROR,Overflow!\n");
else
{
s->top++;
s->stack[s->top]=x;
}
}
//9.若栈为空,返回TRUE,否则返回FASLE
bool StackEmpty(sqstack s)
{
if(s.top ==0) return true;
else return false;
}
//4.主要表达式函数
int EvaluateExpression()
{
char c;
int i=0,sum=0;
int k=1,j=1; //设置开关变量
elemtype x,t,a,b;
sqstack OPTR,OPND;
Initstack(&OPTR);
Push(&OPTR,cton('#')); //‘#’压入栈
Initstack(&OPND);
c=getchar();
while(c!='#'||ch[Gettop(OPTR)]!='#')
{
if(isdigit(c)) //判断c是否为数字
{
sum=0;
while(isdigit(c))
{
if(!j) //j用来进行字符串转换判断,j为0转换
{
sum=sum*10-(c-'0');
}
else sum=sum*10+(c-'0'); //字符c转化成对应数字
c=getchar();
}
Push(&OPND,sum); //当前c无为数字,则把之前的数字串转换为十进制数字再压
j=1;
}
else if(k)
{
switch(Compare(ch[Gettop(OPTR)],c))
{
case '<': Push(&OPTR,cton(c)); //把字符整型化,然后压入操作符栈
c=getchar();
break;
case '=': Pop(&OPTR,&x); //操作符栈顶元素出栈
c=getchar();
break;
case '>': Pop(&OPTR,&t); //操作符栈顶元素出栈
Pop(&OPND,&b); //操作数栈顶元素出栈
Pop(&OPND,&a); //操作数栈顶元素出栈
Push(&OPND,Operate(a,t,b));
break;
}
}
}
return (Gettop(OPND));
}
void main()
{
system("color a");
int result;
printf("请输入表达式'#'号结束:\n");
result=EvaluateExpression();
printf("表达式结果为:%d\n",result);
system("pause");
}
结果展示: