C语言数据结构表达式求值问题
用顺序栈实现算术表达式的求值。将表达式堪称字符串序列,输入语法正确,不含有变量的整数表达式(数字仅限个位),利用算符的优先级关系,把中缀表达式转换为后缀表达式输出,然后求出该后缀表达式的值,如输入的表达式为2*(6-4)+8/4,转换后后缀表达式为264-*84/+
程序的基本思路我已经写出了,但是有点问题,而且没有将后缀表达式输出,希望大神们帮忙下~
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAXSIZE 100//定义栈的大小
typedef char ElemType;
typedef struct
{
ElemType data[MAXSIZE];//栈的元素
int top;//栈顶指针,指向栈顶元素
}SeqStack;
SeqStack SeqStackInit()//初始化栈
{
SeqStack s;
s.top=-1;
return s;
}
SeqStack Push(SeqStack s,ElemType x)//入栈操作
{
if(s.top==MAXSIZE-1)
{
printf("对不起,栈已经满了");
exit(0);
}
s.top++;
s.data[s.top]=x;
return s;
}
char Pop(SeqStack s)//弹栈操作
{
ElemType x;
if(s.top==-1)
{
printf("对不起,栈已经空了");exit(0);
}
x=s.data[s.top];
s.top--;
return x;
}
ElemType SeqStackGetTop(SeqStack s)//取栈顶元素
{
if(s.top!=-1)
return (s.data[s.top]);
}
char Precede(char a1 ,char a2)//判定运算符的优先级函数。
{
char r;
switch(a2)
{
case'+':
case'-'://加减运算优先级相同
if(a1=='('||a1=='\n')
r='<';
else
r='>';
break;
case'*':
case'/': //乘除运算优先级相同
if(a1=='*'||a1=='/'||a1==')')
r='>';
else
r='<';
break;
case'(':
if(a1==')')
{
printf("括号匹配错误!");
exit(-1);
}
else
r='<';
break;
case')':
if(a1=='(')
r='=';
else if(a1=='\n')
{
printf("error!没有左括号");
exit (-1);
}
else
r='>';
break;
case'\n':
switch(a1)
{
case'\n':
r='=';
break;
case'(':
printf("error!没有右括号");
exit(-1);
default:
r='>';
}
break;
}
return r;
}
char operate(char a,char theta,char b)
{
switch(theta)
{
case '+': return (a-'0')+(b-'0');
case '-': return a-b+'0';
case '*': return (a-'0')*(b-'0')+'0';
case '/': return (a-'0')/(b-'0')+'0';
default : return '0';
}
}
char CalculExp()
{
char ch[30],theta,a,b;
int i=0,j;
SeqStack optr,opnd;
optr=SeqStackInit();//初始化运算符栈
opnd=SeqStackInit();//初始化操作数栈
optr=Push(optr,'#');//将'#'置运算符栈底,级别最低
scanf("%s",&ch);//输入表达式,以#结束
for(j=0;j<30;j++)
while(!((ch[i]=='#')&&(SeqStackGetTop(optr)=='#')))//当输入不为#与运算符栈顶元素不为#时
if(ch[i]>='0'&&ch[i]<='9')//对数字进行压操作数栈
{
opnd=Push(opnd,ch[i]);
i++;
}
else switch(Precede(SeqStackGetTop(optr),ch[i]))//否则对运算符栈进行操作
{
case '<':optr=Push(optr,ch[i]);
i++;
break;
case '=':Pop(optr);
i++;
break;
case '>':theta=Pop(optr);
b=Pop(opnd);a=Pop(opnd);
opnd=Push(opnd,operate(a,theta,b));
}
return(SeqStackGetTop(opnd));
}
void main()
{
char q;
q=CalculExp();
printf("所求的表达值的是\n",q-'0');
}
[解决办法]
单步调试下看看什么问题,这么长代码,都不知道你要我输入什么,我按照你要求输入2*(6-4)+8/4
一下子就给我退出来了。说栈满了。我给你提醒下吧。scanf("%s",&ch);//输入表达式,以#结束
应该改为scanf("%s",ch);
后来我又按照你提示的按#结束,输入2*(6-4)+8/4#后,还是栈满退出了。我发现你这个地方
while(!((ch[i]=='#')&&(SeqStackGetTop(optr)=='#')))//当输入不为#与运算符栈顶元素不为#时
if(ch[i]>='0'&&ch[i]<='9')//对数字进行压操作数栈
{
opnd=Push(opnd,ch[i]);
i++;
}
else switch(Precede(SeqStackGetTop(optr),ch[i]))//否则对运算符栈进行操作
{
case '<':optr=Push(optr,ch[i]);
i++;
break;
case '=':Pop(optr);
i++;
break;
case '>':theta=Pop(optr);
b=Pop(opnd);a=Pop(opnd);
opnd=Push(opnd,operate(a,theta,b));
}
就一直进入case '>',一直压栈,把栈压满了。