整数四则混合混算的表达式计算
本文实现整数的四则混合混算。比如:输入(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;}