使命栈(stack)实现一个简易的四则运算计算器

运算过程比较简单。在VC控制台输入 四则运算表达式,以按下回车键来获取运算结果。退出控制台,按下CTRL + 'Z'

/*
 * calculator.cpp
 */
#include 
   
   
    
    
#include 
    
    
     
     
#include "stack.h"

#define EXP_MAX_SIZE 64 

char infix_exp[EXP_MAX_SIZE];
int postfix_exp[EXP_MAX_SIZE];
int result;
int ret_val;

int convert_infix_to_postfix(char *infix_exp, int *postfix_exp);
int postfix_expression_calc(int *postfix_exp, int *result);

/*
 *     9+(3-1)*3+10/2
 * --> 931-3*+102/+
 * --> 20
 */
int main()
{
	memset(infix_exp, 0, EXP_MAX_SIZE);
	memset(postfix_exp, 0, EXP_MAX_SIZE);

	while (fgets(infix_exp, EXP_MAX_SIZE, stdin) != NULL)
	{
		if (ret_val = convert_infix_to_postfix(infix_exp, postfix_exp))
		{	
			printf("Something is wrong.\n");
		}
		if (ret_val = postfix_expression_calc(postfix_exp, &result))
		{	
			/* for simplicity, we won't check errors in called function */
			printf("Something is wrong.\n");
		}

		printf("result is %d\n", result);

		memset(infix_exp, 0, EXP_MAX_SIZE);
		memset(postfix_exp, 0, EXP_MAX_SIZE);
	}

	return 0;
}

/*
 * Infix to Postfix Conversion.
 * #1. When an operand is read, it is immediately placed onto the output.
 * #2. As to operators(including left parenthesis), we start with an intially 
 *     empty stack.
 *     If we see a right parenthesis, then we pop the stack, waiting symbols
 *     until we encounter a(corresponding) left parenthesis, which is popped
 *     but not output.
 *     If we see any other symbol(as our routine, +,-,*,/), then we pop entries
 *     from the stack until we find an entry of lower priority. !!One exception!!
 *     is that we never remove ')' from the stack except when processing a ')'. When
 *     the popping is done, we push the operator onto the stack.
 */
int convert_infix_to_postfix(char *infix_exp, int *postfix_exp)
{
	char *p;
	int *q;
	int top_val;
	int i, num;

	Stack S = NULL;
	S = CreateStack(EXP_MAX_SIZE);

	/* infix_exp terminatted with a '\n' */
	p = infix_exp;
	q = postfix_exp;
	while (1)
	{
		if (*p >= '0' && *p <= '9')
		{
			/* Get a number */
			for (i = 0, num = 0; *(p+i) >= '0' && *(p+i) <= '9'; ++i)
			{
				num = num * 10 + *(p + i) - '0';
			}
			*q++ = num;
			p += i;
			continue;
		}
		else if (*p == '+' || *p == '-')
		{
			if (IsEmpty(S))
			{
				Push(*p, S);
			}
			else
			{
				while (Top(S) != '(')
				{
					*q++ = TopAndPop(S);
					if (IsEmpty(S))
					{
						break;
					}
				}
				Push(*p, S);
			}
		}
		else if (*p == '*' || *p == '/')
		{
			if (IsEmpty(S))
			{
				Push(*p, S);
			}
			else
			{
				while ((top_val = Top(S)) != '(')
				{
					/* Popped entries from the stack until */ 
					/* we find an entry of lower priority */
					if (top_val == '+' || top_val == '-')
					{
						break;
					}
					else  /* '*' or '/' */
					{
						*q++ = TopAndPop(S);
						if (IsEmpty(S))
						{
							break;
						}
					}
				}
				Push(*p, S);
			}
		}
		else if (*p == '(')
		{
			Push(*p, S);
		}
		else if (*p == ')')
		{
			/* if no '(' in the stack because of error input, will cause a fatal error */
			while ((top_val = TopAndPop(S)) != '(')
			{
				*q++ = top_val;
			}
		}
		else if (*p == '\n')
		{
			while (!IsEmpty(S))
			{
				*q++ = TopAndPop(S);
			}
			break;
		}
		else if (*p != ' ')	/* Ignoe white space between operators and operands */
		{
			/* error infix_exp */
			DisposeStack(S);
			return -1;
		}

		++p;
	}

	*q = '\0';

	DisposeStack(S);

	return 0;
}

/*
 * Using Postfix Expressions to calculate
 * When a number is seen, it is pushed onto the stack; when an operator
 * is seen, the operator is applied to the two numbers(symbols) that are
 * popped from the stack, and the result is pushed onto the stack.
 */
int postfix_expression_calc(int *postfix_exp, int *result)
{
	int *p = postfix_exp;
	int a, b;

	Stack S = NULL;
	S = CreateStack(EXP_MAX_SIZE);

	/* postfix_exp terminatted with a '\0' */
	while (*p != '\0')
	{
		if (*p == '+' || *p == '-' || *p == '*' || *p == '/')
		{
			a = TopAndPop(S);
			b = TopAndPop(S);
			if (*p == '+')
			{
				*result = b + a;
			}
			else if (*p == '-')
			{
				*result = b - a;
			}
			else if (*p == '*')
			{
				*result = b * a;
			}
			else if (*p == '/')
			{
				*result = b / a;
			}
			Push(*result, S);
		}
		else
		{
			Push(*p, S);
		}
		++p;
	}

	DisposeStack(S);

	return 0;
}
    
    
   
   
栈的实现过程见  C源码@数据结构与算法->栈Stack

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值