栈应用之中缀表达式转后缀表达式(C语言)

我从网上摘取了几个思路,这里的思路在优先级的比较上大致相同,方法多变,这里不再一一详解。
———————————————————————————————————
1、数字直接输出
2、遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出。
3、遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。
4、遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个优先级,所以也依次弹栈)直到栈空或则遇到左括号为止,停止弹栈。(因为左括号要匹配右括号时才弹出)。
5、获取完后,将栈中剩余的运算符号依次弹栈输出。

———————————————————————————————————
1、首先我们要建立一个集合 sList 来存放例子中的数据和操作符号,一个栈opStack来存放中间的操作符号,一个集合dList 来存放最后的转换结果。
2、从sList中取出一个元素A然后进行以下判断:
(1)如果A是数字,则直接存如dList
(2)如果A是运算符,则和opStack栈顶的元素进行运算优先级比较
(2-1)如果A的优先级高于栈顶运算符优先级,则将A入栈opStack
(2-2)如果A的优先级低于或等于栈顶运算符的优先级,那么将栈顶的元素出栈存入dList,重复此步骤直到栈顶的运算符优先级低于当前运算符(或者遇到括号),然后A入栈。
3、如果A是左括号“(”直接入栈,如果是右括号“)”,则将opStack中的运算符弹出存入dList,直到弹出左括号,左右括号均不存入dList,左括号永远不会弹出,直到遇到右括号。
4、不断重复以上步骤直到表达式解析完成。
———————————————————————————————————
这是另一种思路的代码:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

#define STACK_INIT_SIZE 20
#define STACK_DILA_SIZE 10

typedef char elemtype;

typedef struct
{
	elemtype * base;
	elemtype * top;
	int stacksize;
}sqstack;

void initstack(sqstack*s)
{
	s->base = (elemtype*)malloc(STACK_INIT_SIZE * sizeof(elemtype));
	if (!s->base)
	{
		exit(0);
	}
	s->top = s->base;
	s->stacksize = STACK_INIT_SIZE;
}

void push(sqstack*s, elemtype x)
{
	if (s->top - s->base >= s->stacksize)
	{
		s->base = (elemtype*)realloc(s->base, (STACK_DILA_SIZE + STACK_INIT_SIZE) * sizeof(elemtype));
		if (!s->base)
		{
			exit(0);
		}
		s->top = s->base + STACK_INIT_SIZE;
		s->stacksize = +STACK_DILA_SIZE;
	}
	*(s->top) = x;
	s->top++;
}

void pop(sqstack*s, elemtype*x)
{
	if (s->base == s->top)
	{
		return;
	}
	s->top--;
	*x = *s->top;
}

int stacklen(sqstack*s)
{
	return (s->top - s->base);
}

void clearstack(sqstack*s)
{
	s->top = s->base;
}

void destroystack(sqstack*s)
{
	s->top = NULL; 
	s->base = NULL;
	s->stacksize = 0;
	free(s->base);
}
int main()
{
	sqstack*s = (sqstack*)malloc(sizeof(sqstack));
	initstack(s);
	char c, x;
	scanf_s("%c", &c, sizeof(c));
	while (c != '#')
	{
		while (c >= '0'&&c <= '9')
		{
			printf("%c", c);
			scanf_s("%c", &c, sizeof(c));
			if (c < '0'||c > '9')
			{
				printf(" ");
			}
		}		
		 if (')' == c)
		{
			pop(s, &x);
			while ('(' != x)
			{
				printf("%c", x);
				pop(s, &x);
			}
		}
		else if ('+' == c || '-' == c)
		{
			if (!stacklen(s))
			{
				push(s, c);
			}
			else
			{
				do
				{
					pop(s, &x);
					if ('(' == x)
					{
						push(s, x);
					}
					else
					{
						printf("%c", x);
					}
				} while (stacklen(s) && '(' != x);
				push(s, c);
			}
		}
		else if ('*' == c || '/' == c || '(' == c)
		{
			push(s, c);
		}
		else if ('#' == c)
		{
			break;
		}
		scanf_s("%c", &c, sizeof(c));
	}
	while (stacklen(s))
	{
		pop(s, &x);
		printf("%c", x);
	}
	return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值