#include <stdio.h>
//求表达式的值,形如:(6+5*(2-8)/2) //中缀表达式
//使用栈来实现,方法是先将中缀表达式转换为后缀表达式6528-*2/+, 再将后缀表达式来求值。
//1.转换为后缀表达式的方法是:数字直接保存到后缀表达式中;符号按优选级决定(比较栈中的栈顶和当前表达式的字符的优先级,如果>则入栈, 如果<则将栈顶出栈并保存到后缀表达式中)是入栈还是将栈顶的字符弹出。另外,表达式字符是"("时直接入栈,表达式字符是“)”时,将栈中从栈顶直至遇到“(”的所有符号出栈。
//字符优先级如下:
//假如str1[i]是当前扫描的字符,stack[top]是栈顶
// str[i] stack[top]
//1)+,- < *,/,+,- //出栈顶
//2)+,- > ) //入栈,注意如果(在栈中,则(的优先级是最小的
//3)*,/ < *, / //出栈
//4)*,/ > +,-,( //入栈
//2. 按后缀表达式求值的方法是:
//取后缀表达式的字符,如果是数字,入栈,如果是符号,则弹出前两个栈顶,用符号做运算(注意操作符的顺序),将运算的结果如栈。重复这个步骤直至扫描完后缀表达式。最后的结果在栈顶。
//实例:
//13 //表达式的字符数
//(6+5*(2-8)/2)
#define MAX 1000
int stack[MAX]; //xxl
int top;
void initstack()
{
int i;
top = -1;
for(i=0;i<MAX; i++)
stack[i]=0;
}
int isFull()
{
if(top == MAX-1)
return 1;
return 0;
}
int isEmpty()
{
if(top == -1)
return 1;
return 0;
}
int getTop(int * x)
{
if(isEmpty())
{
return 0;
}
*x=stack[top];
return 1;
}
int pop(int * x)
{
if(isEmpty())
{
return 0;
}
*x=stack[top];
top--;
return 1;
}
int push(int x)
{
if(isFull())
{
return 0;
}
top++;
stack[top]=x;
return 1;
}
int main()
{
int tc;
int i,j;
char str1[MAX];
char str2[MAX];
//int len;
int len2;
int node;
int node1;
int node2;
int Lflag=1;
int r;
int sum;
//freopen("input.txt", "r", stdin); //xxl
for(tc=1; tc<=10 /*xxl*/; tc++) //each case
{
scanf("%d", &len2);
scanf("%s", str1);
initstack();
for(i=0; i<MAX; i++)
{
str2[i]=0;
}
//1---get postfix expression
i=0;
j=0;
while(str1[i]!='\0')
{
if( str1[i]!='+'
&& str1[i]!='-'
&& str1[i]!='*'
&& str1[i]!='/'
&& str1[i]!=')'
&& str1[i]!='(' )
{
str2[j]=str1[i];
j++;
}
else
{
if(str1[i]==')')
{
while(getTop(&node1) && node1 != '(')
{
pop(&node2);
str2[j]=node2;
j++;
}
if(node1 == '(')
{
pop(&node2); //don't need to be saved
}
else
{
//exception?
}
}
else if(str1[i]=='(')
{
push(str1[i]);
}
else // case: + - * /
{
Lflag = 1; //compare str[i] and top, 1=>lower
while(Lflag==1)
{
//excpetion?
r=getTop(&node1); //only char: +,-,*,/,(
if(r==0) //if stack is empty
{
node1='#'; //特殊处理,使得字符能够入栈
}
//4 cases
if(str1[i]=='+' || str1[i]=='-')
{
if(node1=='+' || node1=='-' || node1=='*' || node1=='/')
{
Lflag = 1;
pop(&node2);
str2[j]=node2;
j++;
}
else if(node1=='(' || node1=='#' )
{
Lflag=0;
push(str1[i]);
}
}
else if(str1[i]=='*' || str1[i]=='/')
{
if(node1=='*' || node1=='/' )
{
Lflag = 1;
pop(&node2);
str2[j]=node2;
j++;
}
else if(node1=='+' || node1=='-' || node1=='(' || node1=='#')
{
Lflag=0;
push(str1[i]);
}
}
}//end of while
}
}
i++;
}
while(isEmpty()==0) //pop remaining operators
{
pop(&node2);
str2[j]=node2;
j++;
}
#if 0 //xxl.debug
for(i=0; i<j; i++)
{
printf("%c", str2[i]);
}
printf("\n");
#endif
//2--str2[] is postfix, start to calculate
initstack();
i=0;
while(str2[i]!='\0')
{
if( str2[i]!='+'
&& str2[i]!='-'
&& str2[i]!='*'
&& str2[i]!='/')
{
push(str2[i]);
}
else
{
pop(&node1);
pop(&node2);
if(str2[i]=='+')
{
sum=node2-'0'+node1-'0';
}
else if(str2[i]=='-')
{
sum=node2-node1;
}
else if(str2[i]=='*')
{
sum=(node2-'0')*(node1-'0');
}
else if(str2[i]=='/')
{
sum=(node2-'0')/(node1-'0');
}
node=sum+'0';
push(node);
}
i++;
}
sum=node-'0';
//len=i;
printf("#%d %d\n", tc, sum);
//while
}
return 0;
}
[栈]求中缀表达式的值
最新推荐文章于 2023-03-19 11:01:17 发布