实验题目:
从键盘输入一个表达式,将表达式用字符串保存后,输出表达式。利用栈判断表达式中的括号是否匹配,如匹配计算表达式的值,并输出匹配,否则,输出匹配失败。
功能要求:
能正确判断表达式的括号匹配(括号限圆括弧和方括弧两种)。
若匹配,利用算符优先法计算表达式的值。
计算表达式值的3个相关函数:
In(c)---- //判断c是否为运算符
Precede(θ1, θ2) ----//判断两运算符θ1, θ2的优先关系
Operate(a, θ, b)---- //做四则运算a theta b,返回运算结果
实现要求:
必须用栈实现括号匹配和表达式计算
注意事项:
采取字符串%s的方式输入,大大简化了输入输出操作。
将数组改为全局变量,在求值函数中加入循环,利用数组正确完成表达式求值的相关操作
实验代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef char SElemType;
typedef int Status;
char str[80];
//顺序栈的定义
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 Push(SqStack &S,char 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;
return OK;
}
//顺序栈的出栈
Status Pop(SqStack &S,char &e){
if(S.top == S.base)
return ERROR;
e = *--S.top ;
return OK;
}
//取栈顶元素
char GetTop(SqStack S)
{
if(S.top == S.base )
return ERROR;
return *(S.top -1);
}
//功能函数
//判断表达式中的括号是否匹配
Matching(char *str)
{
SqStack S;
InitStack(S);
int flag = 1;
char *ch,x;
ch = str;
while(*ch!='#'&&flag)
{
switch(*ch)
{
case '[':
case '(':
Push(S,*ch);
break;
case ')':
if(S.top != S.base && GetTop(S)=='(')
Pop(S,x);
else
flag = 0;
break;
case ']':
if(S.top != S.base && GetTop(S)=='[')
Pop(S,x);
else
flag = 0;
break;
}
ch++;
}
if(S.top == S.base && flag)
return 1;
else
return 0;
}
//判断c是否为运算符
int In(SElemType c)
{
switch(c)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':
return 1;
default:
return 0;
}
}
//判断两符号的优先关系
char Precede(SElemType t1, SElemType t2)
{
SElemType f;
switch(t2)
{
case'+':
case'-':
if(t1=='('||t1=='#')
f='<';
else
f='>';
break;
case'*':
case'/':
if(t1=='*'||t1=='/'||t1==')')
f='>';
else
f='<';
break;
case'(':
if(t1==')')
{
printf("括号不匹配\n");
exit(OVERFLOW);
}
else
f='<';
break;
case')':
switch(t1)
{
case'(':
f='=';
break;
case'#':
printf("缺乏左括号\n");
exit(OVERFLOW);
default:
f='>';
}
break;
case'#':
switch(t1)
{
case'#':
f='=';
break;
case'(':
printf("缺乏右括号\n");
exit(OVERFLOW);
default:
f='>';
}
}
return f;
}
//做四则运算a theta b,返回运算结果
SElemType Operate(SElemType a,SElemType theta,SElemType b)
{
switch(theta)
{
case'+':
return a+b;
case'-':
return a-b;
case'*':
return a*b;
}
return a/b;
}
char EvaluateExpression()
{
SqStack OPND,OPTR;
int ch;
char a,b,theta,x;
InitStack(OPND);
InitStack(OPTR);
Push(OPTR,'#');
ch=str[0];
for(int i = 0; i<strlen(str); i++)
{
while(ch!='#'||GetTop(OPTR)!='#')
{
if(!In(ch))
{
ch=ch-48;
Push(OPND,ch);
ch=str[++i];
}
else
{
switch(Precede(GetTop(OPTR),ch))
{
case '<':
Push(OPTR,ch);
ch=str[++i];
break;
case '>':
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
case '=':
Pop(OPTR,x);
ch=str[++i];
break;
}
}
}
}
return GetTop(OPND);
}
//主函数
int main()
{
int choice,result;
printf("***************判断表达式括号匹配***************\n");
printf("1.请输入表达式\n");
printf("2.输出表达式\n");
printf("3.判断表达式的括号是否匹配并计算表达式的值\n");
printf("4.退出\n");
printf("************************************************\n");
while(1)
{
printf("请输入选择1--4:\n");
scanf("%d",&choice);
if(choice>4 || choice<=0)
{
printf("您输入的数据有误!\n");
return 0;
}
while(choice <= 4)
{
if(choice == 1)
{
printf("请输入表达式(以#结尾):\n");
scanf("%s",str);
break;
}
if(choice == 2)
{
printf("输出表达式:\n");
printf("%s\n",str);
break;
}
if(choice == 3)
{
printf("判断括号是否匹配:\n");
if(Matching(str))
{
printf("括号匹配!\n");
result = EvaluateExpression();
printf("表达式的计算结果为:%d\n",result);
break;
}
else
{
printf("OMG!括号匹配不成功!\n");
break;
}
}
if(choice == 4)
{
printf("退出\n");
return 0;
}
}
}
}