栈的学习笔记

200 阅读1分钟

中缀表达式转为后缀表达式

Status Transform(SqStack *s1,SqStack *s2)
{
	//s1为中缀表达式,s2储存转化的后缀表达式 
	char c,data;
	printf("输入中缀表达式,以#为结束标志");	
	scanf("%c",&c);
	while(c != '#') 
	{
		if(isdigit(c))
		{
			//如果为数字压栈s2 
			pushStack(&s2,c);
		}
		else if(c == ')')
		{
			popStack(&s1,&data);
			while(data != '(')
			{
				pushStack(&s2,data);
				popStack(&s1,&data);
			}
		}
		else if('+' || '-')
		{
			//'+''-'优先级低
			if(isEmptyStack(&s1)) 
			{
				//如果为空 
				pushStack(&s2,c);
			}
			else
			{
				do
				{
					popStack(&s1,&data);
					if(data == '(')
					{
						pushStack(&s1,c);
					}
					else
					{
						pushStack(&s2,data);
					}
				}while(isEmptyStack(&s1)|| data == '(');
				pushStack(&s1,c);
			}
		}
		else if(c == '*'||c=='/'||c=='(')
		{
			pushStack(&s1,c);
		}
		else
		{
			printf("出错");
			return ERROR; 
		}
	}
}

后缀表达式的计算

用栈来进出运算的数字

1.从左到右遍历中缀表达式的每一个数字和符号

2.若是数字,则进栈

3.若是符号,则把处于栈顶的两个数字出栈,进行运算

4.运算结果进栈

5.直到获得最终结果

Status calculate(SqStack *s2)
{
	char c=0;
	int i;
	double d,e;
	char str[20];
	c = *++(s2->base);//从栈底读取后缀表达式  
	while(c != '#')
	{
		while ( isdigit(c) || c == '.')
		{
			//过滤数字,剩下操作符 
			str[i++] = c;
			str[i] = '\0';//atof处理字符串 
			if(i >= 20){
				printf("数据过大\n");
				return ERROR; 
			}
			scanf("%c",&c);
			if( c == ' ')
			{
				//读到空格
				d = atof(str);
				pushStack(&s2, d);
				i = 0;
				break; 
			}
		}
		switch(c)
		{
			case '+':
				popStack(&s2,&e);
				popStack(&s2,&e);
				pushStack(&s2, d+e);
				break;
			case '-':
				popStack(&s2,&e);
				popStack(&s2,&d);
				pushStack(&s2, d-e);//先入栈作被减数
				break;
			case '*' :
				popStack(&s2,&e);
				popStack(&s2,&e);
				pushStack(&s2, d*e);
				break;
			case '/':
				popStack(&s2,&e);
				popStack(&s2,&e);
				if(e!=0) pushStack(&s2, d/e);
				else 
				{
					printf("除数为0");
					return ERROR;
				}
				break; 
		}
		c = *++(s2->base);	
 	}
 	c = *++(s2->base);
 	printf("计算结果为:%f\n",d);
}