本文实现整数的四则混合混算。比如:输入(5+8*4+7)*9-3*(13+2*6),返回计算结果为321。

 

思路:正向扫描表达式,使用两个栈分别存储整数和符号,有括号的先计算括号中的值。遇到乘除法先计算。经过以上计算后得到最后的式子为只有加减法的无括号式子。再计算最后结果。

 

流程描述:

1.      扫描字符t。

2.      若为’\0’,跳到4;若为’*/+)’,入符号栈;若为’-‘,转化为(-1)*,分别入数字栈和符号栈;若为数字’0-9’,向前找到不是’0-9’的符号,转化为整数,入数字栈;若为’)’,符号栈依次出栈计算数字栈顶两元素后入数字栈,直到遇到’(‘出栈,跳到3。

3.      t++,跳回1。

4.      符号栈依次出栈计算数字栈数据,直到符号栈为空。跳到5。

5.      数字栈栈顶元素为结果。结束。

输入:符合四则运算的整数数字运算表达式,可以有括号,负数。表达式合法性不在此程序验证范围之内,如果需要验证请在外围加验证函数。

输出:运算表达式结果。

限制:表达式使用的数字栈和符号栈的大小会限制计算的表达式范围;大数加减乘除不在此程序处理;

 

使用例子:

char expession[] = "(5+8*4+7)*9-3*(13+002*6)";
	int ret = calculate_expression(expession);



程序代码:说明,如果想更清楚的了解运算过程和栈的变化,请自行加上栈数据打印函数。

 

程序代码:说明,如果想更清楚的了解运算过程和栈的变化,请自行加上栈数据打印函数。

#define ERROR_VALUE 0xffffffff
#define MAX_STACK 0x10
//数字栈
int int_stack[MAX_STACK];
int is_top=-1;
//数字入栈
bool is_push(int i)
{
	if (is_top<(MAX_STACK-1))
	{
		int_stack[++is_top]=i;
		return true;
	}
	return false;
};
//数字出栈
int is_pop()
{
	if (is_top>=0)
	{
		int p = int_stack[is_top];
		is_top--;
		return p;
	}
	return ERROR_VALUE;
};
//符号栈
char char_stack[MAX_STACK];
int cs_top = -1;
//符号入栈
bool cs_push(char ch)
{
	if (cs_top<(MAX_STACK-1))
	{
		char_stack[++cs_top] = ch;
		return true;
	}
	return false;
};
//符号出栈
char cs_pop()
{
	if (cs_top>=0)
	{
		char p = char_stack[cs_top];
		cs_top--;
		return p;
	}
	return -1;
};

//二元表达式计算
int calculate(int left,int right,char exp)
{
	if (exp == '*')
	{
		return right*left;
	}
	if (exp == '/')
	{
		return left/right;
	}
	if (exp == '+')
	{
		return left+right;
	}
	if (exp == '-')
	{
		return left -right;
	}
	return ERROR_VALUE;
};
//四则混合运算式计算
int calculate_expression(char *expession)
{
	char *t = expession;
	char m;
	int n;
	while(*t!='\0')
	{
		switch (*t)
		{
		case '+':
		case '*':
		case '/':
		case '(':
			cs_push(*t);
			break;
		case '-':
			//使用"+(-1)*"来代替"-",可以避免*(-3),这样的负数带来的影响
			cs_push('+');
			cs_push('*');
			is_push(-1);
			break;
		case ')':
			//数据栈顶两个元素用运算符栈顶的元素计算后入数据栈,要直找到'('的位置才结束计算
			m = cs_pop();
			do 
			{
				int r = is_pop();
				int l = is_pop();
				n = calculate(l,r,m);
				is_push(n);
				m = cs_pop();
			} while (m!='(');

			//把括号左边的最近的乘除法先计算出来,注意,加减不能算,因为括号后面还有可能有乘除法。
			m = cs_pop();
			if ( m=='*' || m == '/')
			{
				int r = is_pop();
				int l = is_pop();
				n = calculate(l,r,m);
				is_push(n);
			}
			else if (m>0)
			{
				cs_push(m);
			}

			break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			{
				//如果有连续-9数字则组合为一个数字进栈
				char str[8];
				int i = 0;
				while( *t>='0' && *t <= '9')
				{
					str[i] = *t;
					i++;
					t++;
				}
				str[i] = '\0';
				t--;

				n = atoi(str);
				is_push(n);

				//把数值左边的最近的乘除法先计算出来,注意,加减不能算,因为数值后面还有可能有乘除法。
				m = cs_pop();
				if ( m=='*' || m == '/')
				{
					int r = is_pop();
					int l = is_pop();
					n = calculate(l,r,m);
					is_push(n);
				}
				else if (m>0)
				{
					cs_push(m);
				}
			}
			break;

		default:
			printf("expression input error!");
			break;
		}
		t++;
	}

	//上面已经做完所有乘法和括号的运算,若还有加减法没做完,把剩下的工作做完
	while ((m = cs_pop())>0)
	{
		int r = is_pop();
		int l = is_pop();
		n = calculate(l,r,m);
		is_push(n);
	}
	printf("the result is %d",n);
	return n;
}