栈应用之逆波兰计算器(C语言)

逆波兰计算器就是用来计算逆波兰表达式的计算器。先谈一谈逆波兰表达式(RPN)吧,逆波兰表达式就是平常说的后缀表达式,即类似数字在前,符号在后的形式。例如:
a+b —> a,b,+
a+(b-c) —> a,b,c,-,+
a+(b-c)d —> a,b,c,-,d,,+
a+d*(b-c)—>a,d,b,c,-,*,+
a=1+3 —> a,1,3,+,=
正常的式子我们叫做中缀表达式,它方便人类的阅读计算,但计算机处理中序表达式(中缀表达式)非常复杂。计算机处理后缀表达式非常简便,因为计算机普遍采用的内存结构是栈式结构,遵循后入先出的原则。只需入栈和出栈两个操作就可以实现逆波兰表达式的计算。如果遇到数字就入栈,如果遇到符号就将栈顶的两个元素出栈并作相应的运算,之后将结果入栈,最终栈中剩下的那个数字就是最终结果。

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

#define STACK_INIT_SIZE 20
#define STACK_DILA_SIZE 10

typedef double 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);
}

int main()
{
	sqstack*s = (sqstack*)malloc(sizeof(sqstack));
	initstack(s);
	char c;
	char str[10] = { '0' };//设置输入单个数字的缓冲区
	int i = 0;
	elemtype a, b, x;
	scanf_s("%c", &c,sizeof(c));
	while (c != '#')
	{
		while (isdigit(c)||c=='.')//过滤数字
		{
			str[i]=c;
			i++;
			scanf_s("%c", &c, sizeof(c));
			if (c == ' ')
			{
				x = atof(str);//将字符型转为double型
				push(s, x);
				i = 0;
				break;
			}
		}
		switch (c)
		{
		case '+':
			pop(s, &a);
			pop(s, &b);
			push(s, a + b);
			break;
		case '-':
			pop(s, &a);
			pop(s, &b);
			push(s, b - a);
			break;
		case '*':
			pop(s, &a);
			pop(s, &b);
			push(s, a*b);
			break;
		case '/':
			pop(s, &a);
			pop(s, &b);
			push(s, b / a);
			break;
		}
		scanf_s("%c", &c, sizeof(c));
	}
	pop(s, &x);
	printf("%f", x);

	return 0;
}

:这个程序有一个弊端,因为计算时数据为double型,在进行除法运算时需要加上小数点,如10.0 5.0 / # 如果不加就会出错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值