上次写的关于字符串表达式计算的方法,逻辑上太过混乱,只是简单的实现!而且还有不少的BUG.写完之后仔细想想计算表达式的方法,才发现一般关于表达式的计算都是利用栈来实现的,这种方法思路很清晰,逻辑很强,而且不容易出错,下面是一个简单的实现:
- //设置运算等级
- int SetLevel(char op)
- {
- int level = 0;
- if ((int)op == 43 || (int)op == 45)
- level = 1;
- if ((int)op == 42 || (int)op == 47)
- level = 2;
- return level;
- }
- //比较优先级
- int Priority(char op_1,char op_2)
- {
- int result = 0;
- if (SetLevel(op_1)-SetLevel(op_2) > 0)
- result = 1;
- if (SetLevel(op_1)-SetLevel(op_2) == 0)
- result = 0;
- if (SetLevel(op_1)-SetLevel(op_2) < 0)
- result = -1;
- return result;
- }
- int calculate(char* str)
- {
- stack<int> stack_Number;
- stack<char> stack_Opreate;
- int result = 0;
- while (*str != '?')
- {
- char temp = 0;
- int i = 0;
- int j = 0;
- //非空栈,将栈内的运算符取出,如果优先级比上一个运算级别高
- //则将数栈连续出栈2次,将2个数用该运算符所计算的值再次压入
- //数栈;如果运算级比上一个级别低,则将级别高的运算符出栈,同
- //样数栈出栈2次参与该运算符号计算,并将值压入数栈,再把该级
- //别低的运算符压入运算符栈;最后当遇到==号时,在按顺序出栈
- //计算.
- char str_Opr = *str;
- switch (str_Opr)
- {
- case '9':case '8':case '7':case '6':case '5':case '4':case '3':case '2':case '1':case '0':
- stack_Number.push(*str-'0');
- break;
- case '+':case '-':case '*':case '/':
- if(stack_Opreate.empty())
- {
- stack_Opreate.push(*str);//如果是空栈,运算符直接入栈,无需比较优先级
- }
- else
- {
- temp = stack_Opreate.top();
- if ( Priority(str_Opr,temp) < 0 )
- {
- stack_Opreate.pop();//将级高的出栈,在把级低的入栈
- stack_Opreate.push('+');
- i = stack_Number.top();
- stack_Number.pop();
- j = stack_Number.top();
- stack_Number.pop();
- if (temp == '*')
- stack_Number.push(i*j);
- if (temp == '/')
- stack_Number.push(j/i);
- }
- if ( Priority(*str,temp) > 0 )
- {
- char new_Opr = *str;//暂存运算符
- ++str;
- i = (*str)-'0';
- j = stack_Number.top();
- stack_Number.pop();
- if (new_Opr == '*')
- stack_Number.push(i*j);
- if (new_Opr == '/')
- stack_Number.push(j/i);
- }
- if ( Priority(*str,temp) == 0 )
- {
- stack_Opreate.push(str_Opr);
- }
- }
- break;
- case '=':
- while (!stack_Opreate.empty())
- {
- i = stack_Number.top();
- stack_Number.pop();
- j = stack_Number.top();
- stack_Number.pop();
- temp = stack_Opreate.top();
- stack_Opreate.pop();
- if (temp == '+')
- stack_Number.push(i+j);
- if (temp == '-')
- stack_Number.push(j-i);
- }
- break;
- }
- str++;
- }
- result = stack_Number.top();
- stack_Number.pop();
- return result;
- }