[栈]求中缀表达式的值

#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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值